pimappsupport/vcardandvcal/src/VCAL.CPP
changeset 0 f979ecb2b13e
child 18 c198609911f9
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15  
       
    16 #include <vcal.h>
       
    17 #include <vutil.h>
       
    18 #include <utf.h>
       
    19 #include <charconv.h>
       
    20 #include "verror.h"
       
    21 #include <vstaticutils.h>
       
    22 #include <vobserv.h>
       
    23 
       
    24 #include <s32mem.h>
       
    25 
       
    26 
       
    27 //
       
    28 // CParserVCal
       
    29 //
       
    30 
       
    31 EXPORT_C CParserVCal* CParserVCal::NewL()
       
    32 /** Allocates and constructs a vCalendar parser.
       
    33 
       
    34 @return Pointer to the newly created vCalendar parser. */
       
    35 	{
       
    36 	CParserVCal* self=new(ELeave) CParserVCal();
       
    37 	CleanupStack::PushL(self);
       
    38 	self->ConstructL();
       
    39 	CleanupStack::Pop();
       
    40 	return self;	
       
    41 	}
       
    42 
       
    43 CParserVCal::CParserVCal() :CVersitParser(ESupportsVersion)
       
    44 	{
       
    45 	iDefaultVersion = KVersitTokenVCalVersionNo;
       
    46 	}
       
    47 
       
    48 EXPORT_C void CParserVCal::InternalizeL(RReadStream& aStream)
       
    49 /** Internalises a vCalendar entity from a read stream.
       
    50 
       
    51 The presence of this function means that the standard templated operator>>() 
       
    52 (defined in s32strm.h) is available to internalise objects of this class.
       
    53 
       
    54 @param aStream Stream from which the vCalendar should be internalised. 
       
    55 @see CVersitParser::InternalizeL() */
       
    56 	{
       
    57 	CVersitParser::InternalizeL(aStream);
       
    58 	}
       
    59 
       
    60 
       
    61 EXPORT_C void CParserVCal::ExternalizeL(RWriteStream& aStream)
       
    62 /** Externalises a vCalendar entity (and all sub-entities) to a write stream. 
       
    63 
       
    64 Sets the entity name to KVersitVarTokenVCALENDAR if it hasn't already been 
       
    65 set.
       
    66 
       
    67 Adds a version property to the start of the current entity's array of properties 
       
    68 if the entity supports this. (If there isn't an array of properties then one 
       
    69 is made).
       
    70 
       
    71 The presence of this function means that the standard templated operator<<() 
       
    72 (defined in s32strm.h) is available to externalise objects of this class.
       
    73 
       
    74 @param aStream Stream to which the vCalendar should be externalised. 
       
    75 @see CVersitParser::ExternalizeL() */
       
    76 	{
       
    77 	if (!iEntityName)
       
    78 		SetEntityNameL(KVersitVarTokenVCALENDAR);
       
    79 	CVersitParser::ExternalizeL(aStream);
       
    80 	}
       
    81 
       
    82 EXPORT_C CVersitParser* CParserVCal::MakeEntityL(TInt aEntityUid,HBufC* aEntityName)
       
    83 // From CVersitParser
       
    84 	{
       
    85 	CVersitParser* newEntity = NULL;
       
    86 
       
    87 	switch (aEntityUid)
       
    88 		{
       
    89 		case KVCalEntityUidVEvent:
       
    90 		case KVCalEntityUidVTodo:
       
    91 			newEntity=CParserVCalEntity::NewL();
       
    92 			CleanupStack::PushL(newEntity);
       
    93 			break;
       
    94 		default: //Allows it to read (and ignore) additional iCalendar entities
       
    95 			newEntity = new(ELeave) CVersitParser(ENoVersionProperty);
       
    96 			CleanupStack::PushL(newEntity);
       
    97 			newEntity->ConstructL();
       
    98 			break;
       
    99 		}
       
   100 	if (iObserver)
       
   101 		iObserver->NewParser(newEntity);
       
   102 	newEntity->SetAutoDetect(iFlags&EUseAutoDetection,iAutoDetectCharSets);
       
   103 	if (iFlags&EImportSyncML)
       
   104 		newEntity->SetFlags(EImportSyncML);
       
   105 
       
   106 	// make child entries aware of default char set
       
   107     if (iFlags&EUseDefaultCharSetForAllProperties)
       
   108 		newEntity->SetFlags(EUseDefaultCharSetForAllProperties);
       
   109 	newEntity->SetDefaultCharSet(DefaultCharSet());
       
   110 	
       
   111 	if (iPlugIn)
       
   112 		{
       
   113 		newEntity->SetPlugIn(iPlugIn);
       
   114 		}
       
   115 
       
   116 	newEntity->InternalizeL(aEntityName, iLineReader);
       
   117 	
       
   118 	CleanupStack::Pop(newEntity);
       
   119 	return newEntity;
       
   120 	}
       
   121 
       
   122 EXPORT_C TUid CParserVCal::RecognizeToken(const TDesC8& aToken) const
       
   123 // From CVersitParser
       
   124 /** Returns a UID that identifies a specified token's type.
       
   125 
       
   126 For example, if aToken contains the property name DAYLIGHT the function returns 
       
   127 KVersitPropertyDaylightUid. If the token is not recognized as vCalendar-specific, 
       
   128 the function calls CVersitParser::RecognizeToken(), which recognizes generic Versit 
       
   129 tokens.
       
   130 
       
   131 @param aToken The token to be recognized.
       
   132 @return A defined UID value if the token has been recognized, KVersitTokenUnknownUid 
       
   133 otherwise. */
       
   134 	{
       
   135 	TUid uid = KNullUid;
       
   136 	TChar firstChar(aToken.Ptr()[0]);
       
   137 	firstChar=firstChar.GetUpperCase();
       
   138 	switch (firstChar)
       
   139 		{
       
   140 	case 'D':
       
   141 		if (!aToken.CompareF(KVersitTokenDAYLIGHT))
       
   142 			uid.iUid = KVersitPropertyDaylightUid;
       
   143 		break;
       
   144 	case 'P':
       
   145 		if (!aToken.CompareF(KVersitTokenPRODID))
       
   146 			uid.iUid = KVersitPropertyHBufCUid;
       
   147 		break;
       
   148 	case 'T':
       
   149 		if (!aToken.CompareF(KVersitTokenTZ))
       
   150 			uid.iUid = KVersitPropertyTimeZoneUid;
       
   151 		break;
       
   152 	case 'V':
       
   153 		if (!aToken.CompareF(KVersitTokenVERSION))
       
   154 			uid.iUid = KVersitTokenVersionUid;
       
   155 		break;
       
   156 	default:
       
   157 		break;
       
   158 		}
       
   159 	if (uid == KNullUid)
       
   160 		return CVersitParser::RecognizeToken(aToken);
       
   161 	return uid;
       
   162 	}
       
   163 
       
   164 EXPORT_C TInt CParserVCal::RecognizeEntityName() const
       
   165 // From CVersitParser
       
   166 /** Tests the current value to see if it a vEvent or vTodo entity.
       
   167 
       
   168 @return KVCalEntityUidVEvent if it is a vEvent entity; KVersitVarTokenVTODO 
       
   169 if it is a vTodo entity; zero if there is no current property or it has no value. */
       
   170 	{
       
   171 	if (iCurrentProperty && iCurrentProperty->Value())
       
   172 		{
       
   173 		TPtrC entityName=STATIC_CAST(CParserPropertyValueHBufC*,iCurrentProperty->Value())->Value();
       
   174 		if (entityName==KVersitVarTokenVEVENT)
       
   175 			return KVCalEntityUidVEvent;
       
   176 		else if (entityName==KVersitVarTokenVTODO)
       
   177 			return KVCalEntityUidVTodo;
       
   178 		}
       
   179 	return 0;
       
   180 	}
       
   181 
       
   182 EXPORT_C void CParserVCal::Reserved1()
       
   183 	{}
       
   184 
       
   185 EXPORT_C void CParserVCal::Reserved2()
       
   186 	{}
       
   187 
       
   188 //
       
   189 // CParserVCalEntity
       
   190 //
       
   191 
       
   192 EXPORT_C CParserVCalEntity* CParserVCalEntity::NewL()
       
   193 /** Allocates and constructs a vCalendar sub-entity parser.
       
   194 
       
   195 @return A pointer to the new vCalendar sub-entity parser. */
       
   196 	{
       
   197 	CParserVCalEntity* self=new(ELeave) CParserVCalEntity();
       
   198 	CleanupStack::PushL(self);
       
   199 	self->ConstructL();
       
   200 	CleanupStack::Pop(self);
       
   201 	return self;	
       
   202 	}
       
   203 
       
   204 CParserVCalEntity::CParserVCalEntity()
       
   205 	: CRecurrenceParser(EFalse)
       
   206 /** Constructs a vCalendar sub-entity parser. */
       
   207 	{}
       
   208 
       
   209 EXPORT_C CParserVCalEntity::~CParserVCalEntity()
       
   210 /** The destructor is empty. */
       
   211 	{
       
   212 	}
       
   213 
       
   214 EXPORT_C void CParserVCalEntity::ExternalizeL(RWriteStream& aStream)
       
   215 /** Externalises a vTodo or vEvent to a write stream.
       
   216 
       
   217 Sets the entity's name to KVersitVarTokenVEVENT if it hasn't already been 
       
   218 set.
       
   219 
       
   220 Converts all date/time values from machine-local into universal time. 
       
   221 
       
   222 The presence of this function means that the standard templated operator<<() 
       
   223 (defined in s32strm.h) is available to externalise objects of this class. 
       
   224 
       
   225 @param aStream Stream to which the vTodo or vEvent should be externalised. */
       
   226 	{
       
   227 	if (!iEntityName)
       
   228 		SetEntityNameL(KVersitVarTokenVEVENT);
       
   229 	CVersitParser::ExternalizeL(aStream);
       
   230 	}
       
   231 
       
   232 EXPORT_C CParserPropertyValue* CParserVCalEntity::MakePropertyValueL(const TUid& aPropertyUid,HBufC16*& aValue)
       
   233 // From CVersitParser
       
   234 	{
       
   235 	if(!aValue && !iLargeDataBuf)
       
   236 		return NULL;
       
   237 
       
   238 	switch (aPropertyUid.iUid)
       
   239 		{
       
   240 		case KVCalPropertyAlarmUid: // won't be recognized except by subclass
       
   241 			{
       
   242 			CVersitAlarm* alarm = MakePropertyValueAlarmL(aValue->Des());
       
   243 			CleanupStack::PushL(alarm);
       
   244 			CParserPropertyValue* value = new(ELeave) CParserPropertyValueAlarm(alarm);
       
   245 			CleanupStack::Pop(alarm);
       
   246 			return value;
       
   247 			}
       
   248 		case KVCalPropertyExtendedAlarmUid: // won't be recognized except by subclass
       
   249 			{
       
   250 			CVersitExtendedAlarm* richAlarm = NULL;
       
   251 			if (aValue)
       
   252 				{
       
   253 				richAlarm = MakePropertyValueExtendedAlarmL(aValue->Des());
       
   254 				}
       
   255 			else
       
   256 				{
       
   257 				richAlarm = MakePropertyValueExtendedAlarmL(*iLargeDataBuf);
       
   258 				}
       
   259 			CleanupStack::PushL(richAlarm);
       
   260 			CParserPropertyValue* value = new(ELeave) CParserPropertyValueExtendedAlarm(richAlarm);
       
   261 			CleanupStack::Pop(richAlarm);
       
   262 			return value;
       
   263 			}
       
   264 		case KVCalPropertyRecurrenceUid:
       
   265 			{
       
   266 			TPtr val=aValue->Des();
       
   267 			return MakePropertyValueRecurrenceL(val);
       
   268 			}
       
   269 		default:
       
   270 			break;
       
   271 		};
       
   272 	return CVersitParser::MakePropertyValueL(aPropertyUid,aValue);
       
   273 	}
       
   274 
       
   275 EXPORT_C CVersitAlarm* CParserVCalEntity::MakePropertyValueAlarmL(TPtr16 aAlarmValue)
       
   276 //Make an Alarm property from stream
       
   277 	{
       
   278 	TPtrC8 propName=iCurrentProperty->Name();
       
   279 	TPtr16 field(NULL,0);
       
   280 
       
   281 	FindFirstField(field,aAlarmValue);
       
   282 	TVersitDateTime* runTime=NULL;
       
   283 	if(field.Length()>0)
       
   284 		runTime = DecodeDateTimeL(field);
       
   285 	CleanupStack::PushL(runTime);
       
   286 	
       
   287 	FindFirstField(field,aAlarmValue);
       
   288 	TTime* snoozeTime = NULL;
       
   289 	if(field.Length()>0)
       
   290 		snoozeTime = DecodeTimePeriodL(field);
       
   291 	CleanupStack::PushL(snoozeTime);
       
   292 
       
   293 	FindFirstField(field,aAlarmValue);
       
   294 	TInt repeatCount=0;
       
   295 	if(field.Length()>0)
       
   296 		Val(field, repeatCount);
       
   297 
       
   298 	if (propName==KVersitTokenAALARM || propName==KVersitTokenMALARM)
       
   299 		FindFirstField(field,aAlarmValue);
       
   300 	else
       
   301 		field.Zero();
       
   302 	
       
   303 	TPtr16 note(NULL,0);
       
   304 	if (propName!=KVersitTokenAALARM)
       
   305 		FindFirstField(note,aAlarmValue);
       
   306 
       
   307 	CVersitAlarm* alarm = CVersitAlarm::NewL(runTime, snoozeTime, repeatCount, field, note);
       
   308 
       
   309 	CleanupStack::Pop(2,runTime);
       
   310 	return alarm; //alarm takes ownership of runTime and snoozeTime
       
   311 	}
       
   312 
       
   313 /** Create a new extended alarm from a stream.
       
   314 The MIME type is set to the creating object's MIME type.
       
   315 The disposition is set to the creating object's disposition.  
       
   316 @param aAlarmValue a pointer to a buffer containing the assocaited data for the alarm. Should not point to an empty 
       
   317 descriptor.
       
   318 @return The newly created extended alarm. */
       
   319 EXPORT_C CVersitExtendedAlarm* CParserVCalEntity::MakePropertyValueExtendedAlarmL(TPtr16 aAlarmValue)
       
   320 	{
       
   321 	TPtrC8 propName=iCurrentProperty->Name();
       
   322 	TPtr16 field(NULL,0);
       
   323 
       
   324 
       
   325 	// Note: the presence of this property means that
       
   326 	// the parameters VALUE and X-CONTENTTYPE should be present; if not
       
   327 	// present, then INLINE rich data shall be assumed
       
   328 
       
   329 	TPtrC8 mimeType(NULL,0);
       
   330 	TPtrC8 dispositionField(NULL,0);
       
   331 
       
   332 	// content-value-type assumes default is INLINE if parameter not present
       
   333 	CVersitExtendedAlarm::TDisposition disposition = CVersitExtendedAlarm::EDispositionInline;
       
   334 
       
   335 	// read in data content-type
       
   336 	CParserParam* alarmParameter = iCurrentProperty->Param(KVersitTokenCONTENTTYPE);
       
   337 
       
   338 	if (alarmParameter)
       
   339 		{
       
   340 		mimeType.Set(alarmParameter->Value());
       
   341 		}
       
   342 
       
   343 	// read in data content-value-type
       
   344 	alarmParameter = iCurrentProperty->Param(KVersitTokenVALUE);
       
   345 		
       
   346 	if (alarmParameter)
       
   347 		{
       
   348 		dispositionField.Set(alarmParameter->Value());
       
   349 		
       
   350 		// if there is a value, convert from text to enum
       
   351 		if (dispositionField.Length())
       
   352 			{
       
   353 			disposition = DecodeDisposition(dispositionField);
       
   354 			}
       
   355 		}
       
   356 		
       
   357 	FindRemainingField(field,aAlarmValue);
       
   358 	CVersitExtendedAlarm* alarm = CVersitExtendedAlarm::NewL(field.Collapse(), mimeType, disposition);
       
   359 
       
   360 	return alarm; 
       
   361 	}
       
   362 	
       
   363 /** Create a new extended alarm from a buffer.
       
   364 The MIME type is set to the creating object's MIME type.
       
   365 The disposition is set to the creating object's disposition. 
       
   366 @param aAlarmValue a reference to a buffer containing the assocaited data for the alarm. Should not be an empty 
       
   367 buffer.
       
   368 @return The newly created extended alarm. */	
       
   369 EXPORT_C CVersitExtendedAlarm* CParserVCalEntity::MakePropertyValueExtendedAlarmL(CBufSeg& aAlarmValue)
       
   370 	{
       
   371 	TPtrC8 propName=iCurrentProperty->Name();
       
   372 	TPtr16 field(NULL,0);
       
   373 
       
   374 
       
   375 	// Note: the presence of this property means that
       
   376 	// the parameters VALUE and CONTENTTYPE should be present; if not
       
   377 	// present, then MIME rich data shall be assumed
       
   378 
       
   379 	TPtrC8 mimeType(NULL,0);
       
   380 	TPtrC8 dispositionField(NULL,0);
       
   381 
       
   382 	// content-value-type assumes INLINE if parameter not present
       
   383 	CVersitExtendedAlarm::TDisposition disposition = CVersitExtendedAlarm::EDispositionInline;
       
   384 
       
   385 	// read in data content-type
       
   386 	CParserParam* alarmParameter = iCurrentProperty->Param(KVersitTokenCONTENTTYPE);
       
   387 
       
   388 	if (alarmParameter)
       
   389 		{
       
   390 		mimeType.Set(alarmParameter->Value());
       
   391 		}
       
   392 
       
   393 	// read in disposition
       
   394 	alarmParameter = iCurrentProperty->Param(KVersitTokenVALUE);
       
   395 		
       
   396 	if (alarmParameter)
       
   397 		{
       
   398 		dispositionField.Set(alarmParameter->Value());
       
   399 		
       
   400 		// if there is a value, convert from text to enum
       
   401 		if (dispositionField.Length())
       
   402 			{
       
   403 			disposition = DecodeDisposition(dispositionField);
       
   404 			}
       
   405 		}
       
   406 		
       
   407 	// read in rich data content
       
   408 	// For this version of MakePropertyValueExtendedAlarmL, we have the 
       
   409 	// data in a CBufSeg that should already have been decoded from BASE64
       
   410 	// (assuming everything else works properly). So we need to get it into 
       
   411 	// a TBufC8
       
   412 	TInt segSize = aAlarmValue.Size();
       
   413 	HBufC8* content = HBufC8::NewLC(segSize);
       
   414 	TPtr8 ptrContent(content->Des());
       
   415 	aAlarmValue.Read(0, ptrContent, segSize);
       
   416 	
       
   417 	CVersitExtendedAlarm* alarm = CVersitExtendedAlarm::NewL(ptrContent, mimeType, disposition);
       
   418 	CleanupStack::PopAndDestroy(content);
       
   419 	
       
   420 	return alarm; 
       
   421 	}
       
   422 
       
   423 /** Used to find the type of the content disposition: inline, URL, or unknown.
       
   424 Converts content-value-type token field to content-value-type enum.
       
   425 @param aContentDisposition The disposition of the data for the alarm action.
       
   426 @return decoded disposition type */
       
   427 EXPORT_C CVersitExtendedAlarm::TDisposition CParserVCalEntity::DecodeDisposition(const TDesC8& aContentDisposition) const
       
   428 	{
       
   429 	if (!aContentDisposition.CompareF(KVersitTokenINLINE))
       
   430 		{
       
   431 		return CVersitExtendedAlarm::EDispositionInline;
       
   432 		};
       
   433 		
       
   434 	if (!aContentDisposition.CompareF(KVersitTokenURL))
       
   435 		{
       
   436 		return CVersitExtendedAlarm::EDispositionUrl;
       
   437 		};
       
   438 	
       
   439 	return CVersitExtendedAlarm::EDispositionUnknown;
       
   440 	}
       
   441 
       
   442 
       
   443 /*
       
   444  * Try to recognize aToken and return a UID for it. 
       
   445  * Call <code>CVersitParser::RecognizeToken()</code>
       
   446  * which recognizes generic Versit tokens if the token has not been 
       
   447  * recognized in this function 
       
   448  *
       
   449  * @param     " const TDesC8& aToken "
       
   450  *            The token to be recognized
       
   451  * @return    " TUid "
       
   452  *            a defined UID value if the token has been recognized, 
       
   453  *				<code>KVersitTokenUnknownUid</code>, otherwise
       
   454  */
       
   455 
       
   456 EXPORT_C TUid CParserVCalEntity::RecognizeToken(const TDesC8& aToken) const
       
   457 // From CVersitParser
       
   458 	{
       
   459 	TUid uid = KNullUid;
       
   460 	TChar firstChar(aToken.Ptr()[0]);
       
   461 	firstChar=firstChar.GetUpperCase();
       
   462 	switch (firstChar)
       
   463 		{
       
   464 	case 'A':	
       
   465 		if (!aToken.CompareF(KVersitTokenAALARM))
       
   466 			uid.iUid = KVCalPropertyAlarmUid;
       
   467 		else if (!aToken.CompareF(KVersitTokenATTENDEE))
       
   468 			uid.iUid = KVersitPropertyHBufCUid;
       
   469 		else if (!aToken.CompareF(KVersitTokenATTACH))
       
   470 			{
       
   471 			if(iCurrentProperty)
       
   472 				{//If it is internalising, iCurrentProperty is set
       
   473 				uid.iUid = KVersitPropertyBinaryUid;//In vCal standard, default value is binary
       
   474 				CParserParam* valueParam = iCurrentProperty->Param(KVersitTokenVALUE);
       
   475 				if (valueParam)
       
   476 					{
       
   477 					TPtrC8 pParameterValue(valueParam->Value());
       
   478 					
       
   479 					if (pParameterValue.CompareF(KVersitTokenINLINE) && pParameterValue.CompareF(KVersitTokenBINARY))
       
   480 						{//If VALUE isn't specified as INLINE or BINARY, value is text type.
       
   481 						uid.iUid = KVersitPropertyHBufCUid;			
       
   482 						}
       
   483 					}
       
   484 				}
       
   485 			}
       
   486 		break;
       
   487 	case 'C':
       
   488 		if (!aToken.CompareF(KVersitTokenCATEGORIES))
       
   489 			uid.iUid = KVersitPropertyCDesCArrayUid;
       
   490 		else if (!aToken.CompareF(KVersitTokenCLASS))
       
   491 			uid.iUid = KVersitPropertyHBufCUid;
       
   492 		else if (!aToken.CompareF(KVersitTokenCOMPLETED))
       
   493 			uid.iUid = KVersitPropertyDateTimeUid;
       
   494 		break;
       
   495 	case 'D':
       
   496 		if (!aToken.CompareF(KVersitTokenDALARM))
       
   497 			uid.iUid = KVCalPropertyAlarmUid;
       
   498 		else if (!aToken.CompareF(KVersitTokenDCREATED) ||
       
   499 				!aToken.CompareF(KVersitTokenDTEND) ||
       
   500 				!aToken.CompareF(KVersitTokenDTSTART) ||
       
   501 				!aToken.CompareF(KVersitTokenDUE))
       
   502 			uid.iUid = KVersitPropertyDateTimeUid;
       
   503 		else if(!aToken.CompareF(KVersitTokenDESCRIPTION))
       
   504 			uid.iUid = KVersitPropertyHBufCUid;
       
   505 		break;
       
   506 	case 'E':
       
   507 		if (!aToken.CompareF(KVersitTokenEXDATE))
       
   508 			uid.iUid = KVersitPropertyMultiDateTimeUid;
       
   509 		else if (!aToken.CompareF(KVersitTokenEXRULE))
       
   510 			uid.iUid = KVCalPropertyRecurrenceUid;
       
   511 		break;
       
   512 	case 'G':
       
   513 		if (!aToken.CompareF(KVersitTokenGEO))
       
   514 			uid.iUid = KVersitPropertyHBufCUid;
       
   515 		break;	
       
   516 	case 'L':
       
   517 		if (!aToken.CompareF(KVersitTokenLASTMODIFIED))
       
   518 			uid.iUid = KVersitPropertyDateTimeUid;
       
   519 		else if(!aToken.CompareF(KVersitTokenLOCATION))
       
   520 			uid.iUid = KVersitPropertyHBufCUid;
       
   521 		break;
       
   522 	case 'M':
       
   523 		if (!aToken.CompareF(KVersitTokenMALARM))
       
   524 			uid.iUid = KVCalPropertyAlarmUid;
       
   525 		break;
       
   526 	case 'P':
       
   527 		if (!aToken.CompareF(KVersitTokenPALARM))
       
   528 			uid.iUid = KVCalPropertyAlarmUid;
       
   529 		else if (!aToken.CompareF(KVersitTokenPRIORITY))
       
   530 			uid.iUid = KVersitPropertyIntUid;
       
   531 		break;
       
   532 	case 'R':
       
   533 		if(!aToken.CompareF(KVersitTokenRDATE))
       
   534 			uid.iUid = KVersitPropertyMultiDateTimeUid;
       
   535 		else if (!aToken.CompareF(KVersitTokenRELATEDTO))
       
   536 			uid.iUid = KVersitPropertyHBufCUid;
       
   537 		else if (!aToken.CompareF(KVersitTokenRESOURCES))
       
   538 			uid.iUid = KVersitPropertyCDesCArrayUid;
       
   539 		else if (!aToken.CompareF(KVersitTokenRNUM))
       
   540 			uid.iUid = KVersitPropertyIntUid;
       
   541 		else if (!aToken.CompareF(KVersitTokenRRULE))
       
   542 			uid.iUid = KVCalPropertyRecurrenceUid;
       
   543 		break;
       
   544 	case 'S':
       
   545 		if (!aToken.CompareF(KVersitTokenSEQUENCE))
       
   546 			uid.iUid = KVersitPropertyIntUid;
       
   547 		else if (!aToken.CompareF(KVersitTokenSTATUS) ||
       
   548 				!aToken.CompareF(KVersitTokenSUMMARY))
       
   549 			uid.iUid = KVersitPropertyHBufCUid;
       
   550 		break;
       
   551 	case 'T':
       
   552 		if(!aToken.CompareF(KVersitTokenTRANSP))
       
   553 			uid.iUid = KVersitPropertyIntUid;
       
   554 		break;
       
   555 	case 'U':
       
   556 		if (!aToken.CompareF(KVersitTokenURL) ||
       
   557 			!aToken.CompareF(KVersitTokenUID))
       
   558 		uid.iUid = KVersitPropertyHBufCUid;
       
   559 		break;
       
   560 	case 'X':
       
   561 		if (!aToken.CompareF(KVersitTokenXRECURRENCEID) ||
       
   562 			!aToken.CompareF(KVersitTokenXDTSTAMP))
       
   563 			{
       
   564 			uid.iUid = KVersitPropertyDateTimeUid;
       
   565 			}
       
   566 		else if (!aToken.CompareF(KVersitTokenXALARM))
       
   567 			{
       
   568 			uid.iUid = KVCalPropertyExtendedAlarmUid;
       
   569 			}
       
   570 		else if (!aToken.CompareF(KVersitTokenXLOCALUID))
       
   571 		    {
       
   572 			uid.iUid = KVersitPropertyIntUid;
       
   573 		    }
       
   574 		break;
       
   575 		}
       
   576 	if (uid == KNullUid)
       
   577 		return CVersitParser::RecognizeToken(aToken);
       
   578 	return uid;
       
   579 	}
       
   580 
       
   581 EXPORT_C void CParserVCalEntity::Reserved1()
       
   582 	{}
       
   583 
       
   584 EXPORT_C void CParserVCalEntity::Reserved2()
       
   585 	{}
       
   586 
       
   587 
       
   588 //
       
   589 // CVersitAlarm
       
   590 //
       
   591 
       
   592 CVersitAlarm::CVersitAlarm(TInt aRepeatCount)
       
   593 	: iRepeatCount(aRepeatCount)
       
   594 	{
       
   595 	}
       
   596 
       
   597 void CVersitAlarm::ConstructL(const TDesC& aAudioContent, const TDesC& aNote, TVersitDateTime* aRunTime, TTime* aSnoozeTime)
       
   598 	{
       
   599 	if (aAudioContent.Size())
       
   600 		{
       
   601 		iAudioContent = aAudioContent.AllocL();
       
   602 		}
       
   603 	if (aNote.Size())
       
   604 		{
       
   605 		iNote = aNote.AllocL();
       
   606 		}
       
   607 	iRunTime = aRunTime;
       
   608 	iSnoozeTime = aSnoozeTime;
       
   609 	}
       
   610 
       
   611 EXPORT_C CVersitAlarm* CVersitAlarm::NewL(TVersitDateTime* aRunTime, TTime* aSnoozeTime, TInt aRepeatCount, const TDesC& aAudioContent, const TDesC& aNote)
       
   612 /** Allocates and constructs a new alarm.
       
   613 
       
   614 Ownership of aRunTime and aSnoozeTime is taken in the end.
       
   615 
       
   616 @param aRunTime Pointer to the alarm time. 
       
   617 @param aSnoozeTime Pointer to the snooze time (may be NULL). 
       
   618 @param aRepeatCount The repeat count. 
       
   619 @param aAudioContent A binary buffer containing the sound data. May be an empty 
       
   620 descriptor. 
       
   621 @param aNote A descriptor containing text to display when the alarm is executing. 
       
   622 May be an empty descriptor. 
       
   623 @return Pointer to the newly created alarm. */
       
   624 	{
       
   625 	CVersitAlarm* self = new(ELeave) CVersitAlarm(aRepeatCount);
       
   626 	CleanupStack::PushL(self);
       
   627 	self->ConstructL(aAudioContent, aNote, aRunTime, aSnoozeTime);
       
   628 	CleanupStack::Pop(self);
       
   629 	return self;	
       
   630 	}
       
   631 
       
   632 EXPORT_C CVersitAlarm::~CVersitAlarm()
       
   633 /** Frees all resources owned by the alarm, prior to its destruction. */
       
   634 	{
       
   635 	delete iRunTime;
       
   636 	delete iSnoozeTime;
       
   637 	delete iAudioContent;
       
   638 	delete iNote;
       
   639 	}
       
   640 
       
   641 CVersitExtendedAlarm::CVersitExtendedAlarm()
       
   642 	{
       
   643 	}
       
   644 
       
   645 void CVersitExtendedAlarm::ConstructL(const TDesC8& aContent, const TDesC8& aContentMimeType, CVersitExtendedAlarm::TDisposition aContentDisposition) 
       
   646 	{
       
   647 	if (aContent.Size())
       
   648 		{
       
   649 		iContent = aContent.AllocL();		
       
   650 		}
       
   651 	else
       
   652 		{
       
   653 		iContent = NULL;
       
   654 		}
       
   655 		
       
   656 	if (aContentMimeType.Size())
       
   657 		{
       
   658 		iMimeType = aContentMimeType.AllocL();
       
   659 		}
       
   660 	else
       
   661 		{
       
   662 		iMimeType = NULL;
       
   663 		}
       
   664 	iDisposition = aContentDisposition;
       
   665 	}
       
   666 
       
   667 /** Allocates and constructs a new extended alarm (X-EPOCALARM).
       
   668 @param aContent A binary buffer containing the assocaited data for the alarm. Should not be empty 
       
   669 descriptor.
       
   670 @param aContentMimeType The MIME type of the data describing the action for the alarm.  
       
   671 @param aContentDisposition The disposition of the data for the alarm action.
       
   672 @return Pointer to the newly created extended alarm. */
       
   673 EXPORT_C CVersitExtendedAlarm* CVersitExtendedAlarm::NewL(const TDesC8& aContent, const TDesC8& aContentMimeType,
       
   674 						   			CVersitExtendedAlarm::TDisposition aContentDisposition)
       
   675 	{
       
   676 	CVersitExtendedAlarm * self = new(ELeave) CVersitExtendedAlarm();
       
   677 	CleanupStack::PushL(self);
       
   678 	self->ConstructL(aContent, aContentMimeType, aContentDisposition);
       
   679 	CleanupStack::Pop(self);
       
   680 	return self;	
       
   681 	}
       
   682 
       
   683 EXPORT_C CVersitExtendedAlarm::~CVersitExtendedAlarm()
       
   684 /** Frees all resources owned by the alarm, prior to its destruction. */
       
   685 	{
       
   686 	delete iContent;
       
   687 	delete iMimeType;
       
   688 	}
       
   689 
       
   690 //
       
   691 // CParserPropertyValueAlarm
       
   692 //
       
   693 EXPORT_C CParserPropertyValueAlarm::CParserPropertyValueAlarm(CVersitAlarm* aValue)
       
   694 : CParserTimePropertyValue(TUid::Uid(KVCalPropertyAlarmUid))
       
   695 	,iValue(aValue)
       
   696 /** Constructs a new alarm property value with a pointer to a CVersitAlarm.
       
   697 
       
   698 @param aValue Pointer to the alarm. The property value takes ownership of 
       
   699 the pointer. */
       
   700 	{}
       
   701 
       
   702 
       
   703 EXPORT_C CParserPropertyValueAlarm::~CParserPropertyValueAlarm()
       
   704 /** Frees all resources owned by the property value, prior to its destruction. */
       
   705 	{
       
   706 	delete iValue;
       
   707 	}
       
   708 
       
   709 EXPORT_C void CParserPropertyValueAlarm::ConvertAllDateTimesToUTCL(const TTimeIntervalSeconds& aIncrement, const CVersitDaylight* aDaylight)
       
   710 /** Converts the alarm time into universal time.
       
   711 
       
   712 The date/time of the alarm is checked against the daylight saving information 
       
   713 provided in aDaylight. If it falls inside the daylight saving period then 
       
   714 the daylight saving offset is subtracted from the time to convert it to universal 
       
   715 time. Otherwise aIncrement is added to the date/time of the alarm to convert 
       
   716 it to universal time.
       
   717 
       
   718 Note that the daylight savings offset will adjust the time both for the daylight 
       
   719 saving and for the time zone.
       
   720 
       
   721 The function has no effect if the value is already stored as universal time.
       
   722 
       
   723 If aDaylight is a NULL pointer then aIncrement is used.
       
   724 
       
   725 @param aIncrement A time interval in seconds which represents the negative 
       
   726 of the time zone of the originating machine. For instance, if the time zone 
       
   727 is +04:30, aIncrement should be set to -04:30.
       
   728 @param aDaylight Pointer to the specification for daylight saving. If the alarm's 
       
   729 time value is within the period for daylight saving, the value is modified 
       
   730 by the daylight saving offset (which accounts for both the time zone and daylight 
       
   731 saving rule). 
       
   732 @deprecated since 9.1
       
   733 */
       
   734 	{
       
   735 	if (iValue && iValue->iRunTime && (iValue->iRunTime->iRelativeTime != TVersitDateTime::EIsUTC) && !iValue->iRunTime->IsFlagSet(TVersitDateTime::EExportLeaveAsLocalTime))
       
   736 		{
       
   737 		ConvertDateTime(&iValue->iRunTime->iDateTime,aIncrement, aDaylight);
       
   738 		iValue->iRunTime->iRelativeTime = TVersitDateTime::EIsUTC;		
       
   739 		}
       
   740 	}	
       
   741 
       
   742 EXPORT_C void CParserPropertyValueAlarm::ConvertAllUTCDateTimesToMachineLocalL(const TTimeIntervalSeconds& aIncrement)
       
   743 /** Converts the alarm time to machine-local time. 
       
   744 
       
   745 This involves adjusting the alarm's date/time by the offset in aIncrement.
       
   746 
       
   747 The function has no effect if the value is already stored as machine-local 
       
   748 time.
       
   749 
       
   750 @param aIncrement A time interval which represents the number of seconds which 
       
   751 is to be added to the date/time value. This should normally be the universal 
       
   752 time offset for the machine's locale. 
       
   753 @deprecated since 9.1
       
   754 */
       
   755 	{
       
   756 	if (iValue && iValue->iRunTime && (iValue->iRunTime->iRelativeTime == TVersitDateTime::EIsUTC))
       
   757 		{
       
   758 		ConvertDateTime(&iValue->iRunTime->iDateTime, aIncrement,NULL);
       
   759 		iValue->iRunTime->iRelativeTime = TVersitDateTime::EIsMachineLocal;
       
   760 		}
       
   761 	}
       
   762 
       
   763 EXPORT_C void CParserPropertyValueAlarm::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& aEncodingCharset,TInt aLengthOutput)
       
   764 	// From CParserProperty
       
   765 /** Externalises the alarm property value into aStream.
       
   766 
       
   767 @param aStream Stream to which the value should be externalised.
       
   768 @param aEncodingCharset Contains the character set and encoding into which the 
       
   769 property value should be converted.
       
   770 @param aLengthOutput The amount of text that has been outputted on the line 
       
   771 so far, which needs to be taken into account when calculating if and where 
       
   772 any line break should occur. */
       
   773 	{
       
   774 	if (!iValue)
       
   775 		return;
       
   776 
       
   777 	TInt bufLen=64;		//This should cover the Date/Time, Duration, Repeat Count and semi colons
       
   778 	if (iValue->iAudioContent)
       
   779 		bufLen+=iValue->iAudioContent->Length();
       
   780 	if (iValue->iNote)
       
   781 		bufLen+=iValue->iNote->Length();
       
   782 	HBufC* outputStringBuf=HBufC::NewLC(bufLen);
       
   783 	TPtr outputString=outputStringBuf->Des();
       
   784 	TBuf8<KVersitDefaultBufferSize> buf;
       
   785 	if (iValue->iRunTime)
       
   786 		{
       
   787 		EncodeVersitDateTimeL(buf,*iValue->iRunTime);
       
   788 		Append(outputString,buf);
       
   789 		}
       
   790 	outputString.Append(KVersitTokenSemiColonUnicode);
       
   791 	if (iValue->iSnoozeTime)
       
   792 		{
       
   793 		EncodeTimePeriodL(buf,*iValue->iSnoozeTime);
       
   794 		Append(outputString,buf);
       
   795 		}
       
   796 	outputString.Append(KVersitTokenSemiColonUnicode);
       
   797 	__ASSERT_DEBUG(iValue->iRepeatCount < 100000, User::Invariant());
       
   798 	if(iValue->iRepeatCount>0)
       
   799 		{
       
   800 		outputString.AppendNum(iValue->iRepeatCount);
       
   801 		}
       
   802 	outputString.Append(KVersitTokenSemiColonUnicode);
       
   803 
       
   804 	if (iValue->iAudioContent)
       
   805 		{
       
   806 		outputString.Append(*iValue->iAudioContent);
       
   807 		if (iValue->iNote)
       
   808 			outputString.Append(KVersitTokenSemiColonUnicode);
       
   809 		}
       
   810 	if (iValue->iNote)
       
   811 		outputString.Append(*iValue->iNote);
       
   812 	FoldAndWriteValueToStreamL(aStream,outputString,aEncodingCharset,aLengthOutput);
       
   813 	CleanupStack::PopAndDestroy(outputStringBuf);
       
   814 	}
       
   815 
       
   816 EXPORT_C TBool CParserPropertyValueAlarm::IsAsciiCharacterSetSufficient()
       
   817 /** Tests whether the property value can be represented using the ASCII character 
       
   818 set.
       
   819 
       
   820 @return ETrue if the property value can be represented using the ASCII character 
       
   821 set. If not, EFalse. */
       
   822 	{
       
   823 	if	(!iValue)
       
   824 		return ETrue;
       
   825 	if (iValue->iAudioContent && !VersitUtils::DescriptorContainsOnlySevenBitCharacters(*iValue->iAudioContent))
       
   826 		return EFalse;
       
   827 	if (iValue->iNote && !VersitUtils::DescriptorContainsOnlySevenBitCharacters(*iValue->iNote))
       
   828 		return EFalse;
       
   829 	return ETrue;
       
   830 	}
       
   831 
       
   832 //
       
   833 // CParserPropertyValueExtendedAlarm. 
       
   834 //
       
   835 EXPORT_C CParserPropertyValueExtendedAlarm::CParserPropertyValueExtendedAlarm(CVersitExtendedAlarm* aValue)
       
   836 : CParserTimePropertyValue(TUid::Uid(KVCalPropertyExtendedAlarmUid))
       
   837 	,iValue(aValue)
       
   838 /** Constructs a new extended alarm property value with a pointer to a CVersitExtendedAlarm.
       
   839 
       
   840 @param aValue Pointer to the alarm. The property value takes ownership of 
       
   841 the pointer. */
       
   842 	{}
       
   843 
       
   844 EXPORT_C CParserPropertyValueExtendedAlarm::~CParserPropertyValueExtendedAlarm()
       
   845 /** Frees all resources owned by the property value, prior to its destruction. */
       
   846 	{
       
   847 	delete iValue;
       
   848 	}
       
   849 
       
   850 EXPORT_C void CParserPropertyValueExtendedAlarm::ConvertAllDateTimesToUTCL(const TTimeIntervalSeconds& /* aIncrement */, const CVersitDaylight* /* aDaylight */)
       
   851 /** Converts the extended alarm time into universal time.
       
   852 
       
   853 @param aIncrement A time interval in seconds which represents the negative 
       
   854 of the time zone of the originating machine. For instance, if the time zone 
       
   855 is +04:30, aIncrement should be set to -04:30.
       
   856 @param aDaylight Pointer to the specification for daylight saving. If the alarm's 
       
   857 time value is within the period for daylight saving, the value is modified 
       
   858 by the daylight saving offset (which accounts for both the time zone and daylight 
       
   859 saving rule). 
       
   860 @deprecated since 9.1
       
   861 */
       
   862 	{
       
   863 	}	
       
   864 
       
   865 EXPORT_C void CParserPropertyValueExtendedAlarm::ConvertAllUTCDateTimesToMachineLocalL(const TTimeIntervalSeconds& /*aIncrement */)
       
   866 /** Converts the extended alarm time to machine-local time.
       
   867 
       
   868 @param aIncrement A time interval which represents the number of seconds which 
       
   869 is to be added to the date/time value. This should normally be the universal 
       
   870 time offset for the machine's locale. 
       
   871 @deprecated since 9.1
       
   872 */
       
   873 	{
       
   874 	}
       
   875 
       
   876 EXPORT_C void CParserPropertyValueExtendedAlarm::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& aEncodingCharset,TInt aLengthOutput)
       
   877 // From CParserProperty
       
   878 /** Externalises the extended alarm property value into aStream.
       
   879 
       
   880 @param aStream Stream to which the value should be externalised.
       
   881 @param aEncodingCharset Contains the character set and encoding into which the 
       
   882 property value should be converted.
       
   883 @param aLengthOutput The amount of text that has been outputted on the line 
       
   884 so far, which needs to be taken into account when calculating if and where 
       
   885 any line break should occur. */
       
   886 	{
       
   887 	if (!iValue)
       
   888 		{
       
   889 		return;
       
   890 		}
       
   891 	// There are two encoding possibilities for this value. If it is a URL, then we expand the 8 bit string,
       
   892 	// which we know is US ASCII into Unicode and append it. If it is INLINE data, then we must encode it as 
       
   893 	// 64 bit data
       
   894 	switch (iValue->iDisposition)
       
   895 		{
       
   896 		case CVersitExtendedAlarm::EDispositionUrl:
       
   897 			ExternalizeUrlL(aStream, aEncodingCharset, aLengthOutput);
       
   898 			break;
       
   899 		case CVersitExtendedAlarm::EDispositionInline:
       
   900 		default:  //intentional fall through, we'll treat any unknown as INLINE data
       
   901 			ExternalizeInlineL(aStream, aEncodingCharset, aLengthOutput);
       
   902 			break;
       
   903 		}
       
   904 	
       
   905 	}
       
   906 
       
   907 void CParserPropertyValueExtendedAlarm::ExternalizeUrlL(RWriteStream& aStream,const Versit::TEncodingAndCharset& aEncodingCharset,TInt aLengthOutput)
       
   908 	{
       
   909 	TInt bufLen = 0;
       
   910 	if (iValue->iContent)
       
   911 		{
       
   912 		bufLen+=iValue->iContent->Size();		
       
   913 		}
       
   914 	
       
   915 	HBufC* outputStringBuf=HBufC::NewLC(bufLen);
       
   916 
       
   917 	TPtr outputString=outputStringBuf->Des();
       
   918 		
       
   919 	HBufC* bufferUrl = NULL;
       
   920 
       
   921 	CVersitUnicodeUtils* vUtils = new(ELeave)CVersitUnicodeUtils();
       
   922 	vUtils->CreateConverterL();
       
   923 
       
   924 	bufferUrl = vUtils->WidenL(*(iValue->iContent));
       
   925 
       
   926 	TPtrC desUrl(bufferUrl->Des());
       
   927 	CleanupStack::PushL(bufferUrl);
       
   928 
       
   929 	outputString.Append(desUrl);
       
   930 
       
   931 	FoldAndWriteValueToStreamL(aStream,outputString,aEncodingCharset,aLengthOutput);
       
   932 	
       
   933 	CleanupStack::PopAndDestroy(2,outputStringBuf);
       
   934 	
       
   935 	}
       
   936 
       
   937 const TInt KBase64MaxLineLength = 64; // chars
       
   938 
       
   939 void CParserPropertyValueExtendedAlarm::ExternalizeInlineL(RWriteStream& aStream,const Versit::TEncodingAndCharset& /*aEncodingCharset*/,TInt /*aLengthOutput*/)
       
   940 	{
       
   941 	if (iValue->iContent)
       
   942 		{
       
   943 		const TInt length = iValue->iContent->Size();
       
   944 		if (length >0)
       
   945 			{
       
   946 			CBufSeg* target = CBufSeg::NewL(length);
       
   947 			CleanupStack::PushL(target);
       
   948 
       
   949 			//get the Data Content into a usable buffer
       
   950 			CBufSeg* source = CBufSeg::NewL(length+1);
       
   951 			source->Reset();
       
   952 			source->InsertL(0, *(iValue->iContent));
       
   953 			source->Compress();
       
   954 			CleanupStack::PushL(source);
       
   955 
       
   956 			
       
   957 			//Do the BASE64 Encoding
       
   958 			RBufReadStream readStream;
       
   959 			readStream.Open(*source);
       
   960 			VersitUtils::ConArcEncodeL(readStream, *target, 
       
   961 						VersitUtils::ConArcEncodingUid(Versit::EBase64Encoding));
       
   962 			readStream.Close();
       
   963 
       
   964 			// make sure the  line lengths are appropriate
       
   965 			VersitUtils::WrapLinesL(*target, KBase64MaxLineLength);
       
   966 
       
   967 			// write to output stream
       
   968 			TInt pos=0;
       
   969 			TInt len=target->Size();
       
   970 			while (pos < len)
       
   971 				{
       
   972 				TPtr8 ptr = target->Ptr(pos);
       
   973 				aStream.WriteL(ptr);
       
   974 				pos+=ptr.Length();
       
   975 				}
       
   976 			CleanupStack::PopAndDestroy(2, target);
       
   977 			}
       
   978 		}
       
   979 	aStream.WriteL(KVersitTokenCRLF);
       
   980 	}
       
   981 
       
   982 	
       
   983 EXPORT_C TBool CParserPropertyValueExtendedAlarm::IsAsciiCharacterSetSufficient()
       
   984 /** Tests whether the property value can be represented using the ASCII character 
       
   985 set.
       
   986 
       
   987 @return ETrue if the property value can be represented using the ASCII character 
       
   988 set. If not, EFalse. */
       
   989 	{
       
   990 	if (!iValue)
       
   991 		{
       
   992 		return ETrue;
       
   993 		}
       
   994 	
       
   995 	if (!iValue->iContent)
       
   996 		{
       
   997 		return ETrue;
       
   998 		}
       
   999 	
       
  1000 	if (iValue->iDisposition == CVersitExtendedAlarm::EDispositionUrl)
       
  1001 		{
       
  1002 		return ETrue;
       
  1003 		}
       
  1004 		
       
  1005 	return EFalse;
       
  1006 	}
       
  1007