calendarengines/caldav/src/caldavutils.cpp
branchRCL_3
changeset 31 97232defd20e
equal deleted inserted replaced
30:bd7edf625bdd 31:97232defd20e
       
     1 /*
       
     2 * Copyright (c) 2010 Sun Microsystems, Inc. and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributor:
       
    10 * Maximilian Odendahl
       
    11 *
       
    12 * Contributors:
       
    13 * 
       
    14 * Description: 	various utility classes and functions
       
    15 *				used in Caldav client and server code
       
    16 */
       
    17 
       
    18 #include "caldavutils.h"
       
    19 
       
    20 #include <http\MHTTPAuthenticationCallback.h>
       
    21 #include <http\mhttptransactioncallback.h>
       
    22 #include <http\mhttpdatasupplier.h>
       
    23 #include <http\rhttpheaders.h> 
       
    24 
       
    25 /**
       
    26  * CalDavUtils::CalDavUtils
       
    27  * default constructor
       
    28  */
       
    29 CalDavUtils::CalDavUtils()
       
    30 	{
       
    31 	// No implementation required
       
    32 	}
       
    33 
       
    34 /**
       
    35  * CalDavUtils::~CalDavUtils
       
    36  * default destructor
       
    37  */
       
    38 CalDavUtils::~CalDavUtils()
       
    39 	{
       
    40 	}
       
    41 
       
    42 /**
       
    43  * CalDavUtils::NewLC
       
    44  * first phase construction
       
    45  */
       
    46 CalDavUtils* CalDavUtils::NewLC()
       
    47 	{
       
    48 	CalDavUtils* self = new (ELeave) CalDavUtils();
       
    49 	CleanupStack::PushL(self);
       
    50 	self->ConstructL();
       
    51 	return self;
       
    52 	}
       
    53 
       
    54 /**
       
    55  * CalDavUtils::NewL
       
    56  * first phase construction
       
    57  */
       
    58 CalDavUtils* CalDavUtils::NewL()
       
    59 	{
       
    60 	CalDavUtils* self = CalDavUtils::NewLC();
       
    61 	CleanupStack::Pop(self); // self;
       
    62 	return self;
       
    63 	}
       
    64 
       
    65 /**
       
    66  * CalDavUtils::ConstructL
       
    67  * second phase construction
       
    68  */
       
    69 void CalDavUtils::ConstructL()
       
    70 	{
       
    71 	}
       
    72 
       
    73 /**
       
    74  * CalDavUtils::FixImportIssues
       
    75  * fix import issues
       
    76  */
       
    77 void CalDavUtils::FixImportIssues(TDes8 &aDes)
       
    78 	{
       
    79 	const TUint KICalCarriageReturnChar('\r');
       
    80 	_LIT8(KICalNewlineChar,"\n");
       
    81 	_LIT8(KICalCarriageReturnLineFeed,"\r\n");
       
    82 
       
    83 	TInt ret = aDes.Find(KICalNewlineChar);
       
    84 
       
    85 	while ((ret != KErrNotFound) && (ret == 0 ? ETrue : (aDes[ret - 1]
       
    86 			!= KICalCarriageReturnChar)))
       
    87 		{
       
    88 		aDes.Replace(ret, 1, KICalCarriageReturnLineFeed);
       
    89 		TInt mid = aDes.Mid(ret + 2).Find(KICalNewlineChar);
       
    90 		ret = mid != KErrNone ? mid + ret + 2 : KErrNotFound;
       
    91 		}
       
    92 	}
       
    93 
       
    94 /**
       
    95  * CalDavUtils::FixExportIssues
       
    96  * fix export issues, hopefully can be removed in the future
       
    97  */
       
    98 void CalDavUtils::FixExportIssues(TDes8 &aDes)
       
    99 	{
       
   100 	FixSameTime(aDes);
       
   101 	FindAndRemoveMethod(aDes);
       
   102 	FixBYMONTHDAY(aDes);
       
   103 	FixLineFeed(aDes);
       
   104 	//TODO: using public, nothing is exported
       
   105 	}
       
   106 
       
   107 /**
       
   108  * CalDavUtils::FixLineFeed
       
   109  * fix lidne feed
       
   110  */
       
   111 void CalDavUtils::FixLineFeed(TDes8 &aDes)
       
   112 	{
       
   113 	_LIT8(lf1,"
");
       
   114 	_LIT8(KBackSlashN,"\\n");
       
   115 	TInt ret = aDes.Find(lf1);
       
   116 	while (ret != KErrNotFound)
       
   117 		{
       
   118 		aDes.Replace(ret, lf1().Length(), KBackSlashN);
       
   119 		ret = aDes.Find(lf1);
       
   120 		}
       
   121 	}
       
   122 
       
   123 /**
       
   124  * CalDavUtils::FixSameTime
       
   125  * fix same time
       
   126  */
       
   127 void CalDavUtils::FixSameTime(TDes8 &aDes)
       
   128 	{
       
   129 #define DATELENGTH	15
       
   130 	_LIT8(DTSTART,"DTSTART:");
       
   131 	_LIT8(DTEND,"DTEND:");
       
   132 	_LIT8(DUE,"DUE:");
       
   133 	_LIT8(nine,"9");
       
   134 	_LIT8(five,"5");
       
   135 	_LIT8(VEVENT,"VEVENT");
       
   136 	_LIT8(VTODO,"VTODO");
       
   137 
       
   138 	// add one second if DTSTART and DTEND is the same
       
   139 	// ATTENTION: works only for very simple cases right now
       
   140 	// DTSTART:20090630T000000
       
   141 	// DTEND:20090630T000000
       
   142 	if (aDes.Find(VEVENT) != KErrNone)
       
   143 		{
       
   144 		TInt PosStart = aDes.Find(DTSTART);
       
   145 		TInt PosDue = aDes.Find(DTEND);
       
   146 
       
   147 		if ((PosStart != KErrNone) && (PosDue != KErrNone))
       
   148 			{
       
   149 			TPtrC8 PtrStart = aDes.Mid(PosStart + DTSTART().Length(),
       
   150 					DATELENGTH);
       
   151 			TPtrC8 PtrStop = aDes.Mid(PosDue + DTEND().Length(), DATELENGTH);
       
   152 
       
   153 			if (PtrStart == PtrStop)
       
   154 				{
       
   155 				aDes.Replace(PosDue + DTEND().Length() + DATELENGTH - 1, 1,
       
   156 						nine);
       
   157 				aDes.Replace(PosDue + DTEND().Length() + DATELENGTH - 2, 1,
       
   158 						five);
       
   159 				aDes.Replace(PosDue + DTEND().Length() + DATELENGTH - 3, 1,
       
   160 						nine);
       
   161 				}
       
   162 			}
       
   163 		}
       
   164 
       
   165 	// add one second if DTSTART and DUE is the same
       
   166 	// ATTENTION: works only for very simple cases right now
       
   167 	// DTSTART:20090630T000000
       
   168 	// DUE:20090630T000000
       
   169 
       
   170 	if (aDes.Find(VTODO) != KErrNone)
       
   171 		{
       
   172 		TInt PosStart = aDes.Find(DTSTART);
       
   173 		TInt PosDue = aDes.Find(DUE);
       
   174 
       
   175 		if ((PosStart != KErrNone) && (PosDue != KErrNone))
       
   176 			{
       
   177 			TPtrC8 PtrStart = aDes.Mid(PosStart + DTSTART().Length(),
       
   178 					DATELENGTH);
       
   179 			TPtrC8 PtrStop = aDes.Mid(PosDue + DUE().Length(), DATELENGTH);
       
   180 
       
   181 			if (PtrStart == PtrStop)
       
   182 				{
       
   183 				aDes.Replace(PosDue + DUE().Length() + DATELENGTH - 1, 1, nine);
       
   184 				aDes.Replace(PosDue + DUE().Length() + DATELENGTH - 2, 1, five);
       
   185 				aDes.Replace(PosDue + DUE().Length() + DATELENGTH - 3, 1, nine);
       
   186 				}
       
   187 			}
       
   188 		}
       
   189 	}
       
   190 
       
   191 /**
       
   192  * CalDavUtils::FindAndRemoveMethod
       
   193  * fix wrong method export
       
   194  */
       
   195 void CalDavUtils::FindAndRemoveMethod(TDes8 &aDes)
       
   196 	{
       
   197 	_LIT8(method,"METHOD:PUBLISH\r\n");
       
   198 	TInt Ret = aDes.Find(method);
       
   199 	while (Ret != KErrNotFound)
       
   200 		{
       
   201 		aDes.Delete(Ret, method().Length());
       
   202 		Ret = aDes.Find(method);
       
   203 		}
       
   204 	}
       
   205 
       
   206 /**
       
   207  * CalDavUtils::FixBYMONTHDAY
       
   208  * fix wrong BYMONTHDAY export
       
   209  */
       
   210 void CalDavUtils::FixBYMONTHDAY(TDes8 &aDes)
       
   211 	{
       
   212 	_LIT8(method0,"BYMONTHDAY=0");
       
   213 	_LIT8(method1,"BYMONTHDAY=1");
       
   214 	TInt ret = aDes.Find(method0);
       
   215 	while (ret != KErrNotFound)
       
   216 		{
       
   217 		aDes.Replace(ret, method1().Length(), method1);
       
   218 		ret = aDes.Find(method0);
       
   219 		}
       
   220 	}
       
   221 
       
   222 /**
       
   223  * CalDavUtils::ScanAllowHeaderL
       
   224  * fix scan allow header
       
   225  */
       
   226 void CalDavUtils::ScanAllowHeaderL(RHTTPTransaction &aTransaction,
       
   227 		TCalDAVOptions &aOptions)
       
   228 	{
       
   229 	RStringF Header = aTransaction.Session().StringPool().OpenFStringL(ALLOW);
       
   230 	THTTPHdrVal HeaderVal;
       
   231 	if (aTransaction.Response().GetHeaderCollection().GetField(Header, 0,
       
   232 			HeaderVal) == KErrNone)
       
   233 		{
       
   234 		RStringF FieldValStr = aTransaction.Session().StringPool().StringF(
       
   235 				HeaderVal.StrF());
       
   236 		const TDesC8 &FieldValDesC = FieldValStr.DesC();
       
   237 		HBufC8 *FieldVal = FieldValDesC.AllocLC();
       
   238 		// delete all colons
       
   239 		TInt Pos = FieldVal->Find(colon);
       
   240 		while (Pos != KErrNotFound)
       
   241 			{
       
   242 			FieldVal->Des().Delete(Pos, 1);
       
   243 			Pos = FieldVal->Find(colon);
       
   244 			}
       
   245 		TLex8 Lex(FieldVal->Des());
       
   246 		TBool stop = EFalse;
       
   247 		while (!stop)
       
   248 			{
       
   249 			TPtrC8 Ptr = Lex.NextToken();
       
   250 			stop = Ptr.Length() == 0;
       
   251 			if (Ptr == DELETE)
       
   252 				aOptions.DELETE = ETrue;
       
   253 			else if (Ptr == GET)
       
   254 				aOptions.GET = ETrue;
       
   255 			else if (Ptr == HEAD)
       
   256 				aOptions.HEAD = ETrue;
       
   257 			else if (Ptr == MKCALENDAR)
       
   258 				aOptions.MKCALENDAR = ETrue;
       
   259 			else if (Ptr == MKCOL)
       
   260 				aOptions.MKCOL = ETrue;
       
   261 			else if (Ptr == OPTIONS)
       
   262 				aOptions.OPTIONS = ETrue;
       
   263 			else if (Ptr == PROPFIND)
       
   264 				aOptions.PROPFIND = ETrue;
       
   265 			else if (Ptr == PROPPATCH)
       
   266 				aOptions.PROPPATCH = ETrue;
       
   267 			else if (Ptr == PUT)
       
   268 				aOptions.PUT = ETrue;
       
   269 			else if (Ptr == REPORT)
       
   270 				aOptions.REPORT = ETrue;
       
   271 			else if (Ptr == COPY)
       
   272 				aOptions.COPY = ETrue;
       
   273 			else if (Ptr == POST)
       
   274 				aOptions.POST = ETrue;
       
   275 			else if (Ptr == MOVE)
       
   276 				aOptions.MOVE = ETrue;
       
   277 			else if (Ptr == ACL)
       
   278 				aOptions.ACL = ETrue;
       
   279 			else if (Ptr == LOCK)
       
   280 				aOptions.LOCK = ETrue;
       
   281 			else if (Ptr == UNLOCK)
       
   282 				aOptions.UNLOCK = ETrue;
       
   283 			}
       
   284 		CleanupStack::PopAndDestroy(FieldVal);
       
   285 		}
       
   286 	Header.Close();
       
   287 	}
       
   288 
       
   289 /**
       
   290  * CalDavUtils::ScanDAVHeaderL
       
   291  * scan DAV header
       
   292  */
       
   293 void CalDavUtils::ScanDAVHeaderL(RHTTPTransaction &aTransaction,
       
   294 		TCalDAVOptions &aOptions)
       
   295 	{
       
   296 	RStringF Header = aTransaction.Session().StringPool().OpenFStringL(DAV);
       
   297 	THTTPHdrVal aHeaderVal;
       
   298 	if (aTransaction.Response().GetHeaderCollection().GetField(Header, 0,
       
   299 			aHeaderVal) == KErrNone)
       
   300 		{
       
   301 		RStringF FieldValStr = aTransaction.Session().StringPool().StringF(
       
   302 				aHeaderVal.StrF());
       
   303 		const TDesC8 &FieldValDesC = FieldValStr.DesC();
       
   304 		HBufC8 *FieldVal = FieldValDesC.AllocLC();
       
   305 		// delete all colons
       
   306 		TInt Pos = FieldVal->Find(colon);
       
   307 		while (Pos != KErrNotFound)
       
   308 			{
       
   309 			FieldVal->Des().Delete(Pos, 1);
       
   310 			Pos = FieldVal->Find(colon);
       
   311 			}
       
   312 		TLex8 Lex(FieldVal->Des());
       
   313 		TBool stop = EFalse;
       
   314 		while (!stop)
       
   315 			{
       
   316 			TPtrC8 Ptr = Lex.NextToken();
       
   317 			stop = Ptr.Length() == 0;
       
   318 			if (Ptr == ONE)
       
   319 				aOptions.ONE = ETrue;
       
   320 			else if (Ptr == TWO)
       
   321 				aOptions.TWO = ETrue;
       
   322 			else if (Ptr == THREE)
       
   323 				aOptions.THREE = ETrue;
       
   324 			else if (Ptr == access_control)
       
   325 				aOptions.access_control = ETrue;
       
   326 			else if (Ptr == calendar_access)
       
   327 				{
       
   328 				aOptions.calendar_access = ETrue;
       
   329 				// this is a CalDAV server for sure, MULTIGET and calendar-query is required
       
   330 				// we do not check for this anymore in CCaldavEngine::GetOptions()
       
   331 				aOptions.MULTIGET = ETrue;
       
   332 				aOptions.QUERY = ETrue;
       
   333 				}
       
   334 			else if (Ptr == calendar_schedule)
       
   335 				aOptions.calendar_schedule = ETrue;
       
   336 			else if (Ptr == calendar_auto_schedule)
       
   337 				aOptions.calendar_auto_schedule = ETrue;
       
   338 			else if (Ptr == sync_collection)
       
   339 				aOptions.sync_collection = ETrue;
       
   340 			else if (Ptr == extended_mkcol)
       
   341 				aOptions.extended_mkcol = ETrue;
       
   342 			}
       
   343 		CleanupStack::PopAndDestroy(FieldVal);
       
   344 		}
       
   345 	Header.Close();
       
   346 	}
       
   347 
       
   348 /**
       
   349  * CalDavUtils::EnsureSlashL
       
   350  * ensure trailing slash
       
   351  */
       
   352 HBufC8* CalDavUtils::EnsureSlashL(HBufC8* aIn)
       
   353 	{
       
   354 	if ((aIn == NULL) || (aIn->Right(KSlash().Length()) == KSlash))
       
   355 		return aIn;
       
   356 	else
       
   357 		{
       
   358 		HBufC8 *out = HBufC8::NewL(aIn->Length() + KSlash().Length());
       
   359 		out->Des().Append(*aIn);
       
   360 		out->Des().Append(KSlash);
       
   361 		delete aIn;
       
   362 		aIn = NULL;
       
   363 		return out;
       
   364 		}
       
   365 	}
       
   366 
       
   367 /**
       
   368  * CalDavUtils::EnsureSlashL
       
   369  * ensure trailing slash
       
   370  */
       
   371 HBufC8* CalDavUtils::EnsureSlashL(const TDesC8 &aIn)
       
   372 	{
       
   373 	HBufC8 *out = aIn.AllocL();
       
   374 	return CalDavUtils::EnsureSlashL(out);
       
   375 	}