pimappsupport/vcardandvcal/src/VCAL.CPP
changeset 0 f979ecb2b13e
child 29 12af337248b1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pimappsupport/vcardandvcal/src/VCAL.CPP	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,1007 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+ 
+#include <vcal.h>
+#include <vutil.h>
+#include <utf.h>
+#include <charconv.h>
+#include "verror.h"
+#include <vstaticutils.h>
+#include <vobserv.h>
+
+#include <s32mem.h>
+
+
+//
+// CParserVCal
+//
+
+EXPORT_C CParserVCal* CParserVCal::NewL()
+/** Allocates and constructs a vCalendar parser.
+
+@return Pointer to the newly created vCalendar parser. */
+	{
+	CParserVCal* self=new(ELeave) CParserVCal();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;	
+	}
+
+CParserVCal::CParserVCal() :CVersitParser(ESupportsVersion)
+	{
+	iDefaultVersion = KVersitTokenVCalVersionNo;
+	}
+
+EXPORT_C void CParserVCal::InternalizeL(RReadStream& aStream)
+/** Internalises a vCalendar entity from a read stream.
+
+The presence of this function means that the standard templated operator>>() 
+(defined in s32strm.h) is available to internalise objects of this class.
+
+@param aStream Stream from which the vCalendar should be internalised. 
+@see CVersitParser::InternalizeL() */
+	{
+	CVersitParser::InternalizeL(aStream);
+	}
+
+
+EXPORT_C void CParserVCal::ExternalizeL(RWriteStream& aStream)
+/** Externalises a vCalendar entity (and all sub-entities) to a write stream. 
+
+Sets the entity name to KVersitVarTokenVCALENDAR if it hasn't already been 
+set.
+
+Adds a version property to the start of the current entity's array of properties 
+if the entity supports this. (If there isn't an array of properties then one 
+is made).
+
+The presence of this function means that the standard templated operator<<() 
+(defined in s32strm.h) is available to externalise objects of this class.
+
+@param aStream Stream to which the vCalendar should be externalised. 
+@see CVersitParser::ExternalizeL() */
+	{
+	if (!iEntityName)
+		SetEntityNameL(KVersitVarTokenVCALENDAR);
+	CVersitParser::ExternalizeL(aStream);
+	}
+
+EXPORT_C CVersitParser* CParserVCal::MakeEntityL(TInt aEntityUid,HBufC* aEntityName)
+// From CVersitParser
+	{
+	CVersitParser* newEntity = NULL;
+
+	switch (aEntityUid)
+		{
+		case KVCalEntityUidVEvent:
+		case KVCalEntityUidVTodo:
+			newEntity=CParserVCalEntity::NewL();
+			CleanupStack::PushL(newEntity);
+			break;
+		default: //Allows it to read (and ignore) additional iCalendar entities
+			newEntity = new(ELeave) CVersitParser(ENoVersionProperty);
+			CleanupStack::PushL(newEntity);
+			newEntity->ConstructL();
+			break;
+		}
+	if (iObserver)
+		iObserver->NewParser(newEntity);
+	newEntity->SetAutoDetect(iFlags&EUseAutoDetection,iAutoDetectCharSets);
+	if (iFlags&EImportSyncML)
+		newEntity->SetFlags(EImportSyncML);
+
+	// make child entries aware of default char set
+    if (iFlags&EUseDefaultCharSetForAllProperties)
+		newEntity->SetFlags(EUseDefaultCharSetForAllProperties);
+	newEntity->SetDefaultCharSet(DefaultCharSet());
+	
+	if (iPlugIn)
+		{
+		newEntity->SetPlugIn(iPlugIn);
+		}
+
+	newEntity->InternalizeL(aEntityName, iLineReader);
+	
+	CleanupStack::Pop(newEntity);
+	return newEntity;
+	}
+
+EXPORT_C TUid CParserVCal::RecognizeToken(const TDesC8& aToken) const
+// From CVersitParser
+/** Returns a UID that identifies a specified token's type.
+
+For example, if aToken contains the property name DAYLIGHT the function returns 
+KVersitPropertyDaylightUid. If the token is not recognized as vCalendar-specific, 
+the function calls CVersitParser::RecognizeToken(), which recognizes generic Versit 
+tokens.
+
+@param aToken The token to be recognized.
+@return A defined UID value if the token has been recognized, KVersitTokenUnknownUid 
+otherwise. */
+	{
+	TUid uid = KNullUid;
+	TChar firstChar(aToken.Ptr()[0]);
+	firstChar=firstChar.GetUpperCase();
+	switch (firstChar)
+		{
+	case 'D':
+		if (!aToken.CompareF(KVersitTokenDAYLIGHT))
+			uid.iUid = KVersitPropertyDaylightUid;
+		break;
+	case 'P':
+		if (!aToken.CompareF(KVersitTokenPRODID))
+			uid.iUid = KVersitPropertyHBufCUid;
+		break;
+	case 'T':
+		if (!aToken.CompareF(KVersitTokenTZ))
+			uid.iUid = KVersitPropertyTimeZoneUid;
+		break;
+	case 'V':
+		if (!aToken.CompareF(KVersitTokenVERSION))
+			uid.iUid = KVersitTokenVersionUid;
+		break;
+	default:
+		break;
+		}
+	if (uid == KNullUid)
+		return CVersitParser::RecognizeToken(aToken);
+	return uid;
+	}
+
+EXPORT_C TInt CParserVCal::RecognizeEntityName() const
+// From CVersitParser
+/** Tests the current value to see if it a vEvent or vTodo entity.
+
+@return KVCalEntityUidVEvent if it is a vEvent entity; KVersitVarTokenVTODO 
+if it is a vTodo entity; zero if there is no current property or it has no value. */
+	{
+	if (iCurrentProperty && iCurrentProperty->Value())
+		{
+		TPtrC entityName=STATIC_CAST(CParserPropertyValueHBufC*,iCurrentProperty->Value())->Value();
+		if (entityName==KVersitVarTokenVEVENT)
+			return KVCalEntityUidVEvent;
+		else if (entityName==KVersitVarTokenVTODO)
+			return KVCalEntityUidVTodo;
+		}
+	return 0;
+	}
+
+EXPORT_C void CParserVCal::Reserved1()
+	{}
+
+EXPORT_C void CParserVCal::Reserved2()
+	{}
+
+//
+// CParserVCalEntity
+//
+
+EXPORT_C CParserVCalEntity* CParserVCalEntity::NewL()
+/** Allocates and constructs a vCalendar sub-entity parser.
+
+@return A pointer to the new vCalendar sub-entity parser. */
+	{
+	CParserVCalEntity* self=new(ELeave) CParserVCalEntity();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;	
+	}
+
+CParserVCalEntity::CParserVCalEntity()
+	: CRecurrenceParser(EFalse)
+/** Constructs a vCalendar sub-entity parser. */
+	{}
+
+EXPORT_C CParserVCalEntity::~CParserVCalEntity()
+/** The destructor is empty. */
+	{
+	}
+
+EXPORT_C void CParserVCalEntity::ExternalizeL(RWriteStream& aStream)
+/** Externalises a vTodo or vEvent to a write stream.
+
+Sets the entity's name to KVersitVarTokenVEVENT if it hasn't already been 
+set.
+
+Converts all date/time values from machine-local into universal time. 
+
+The presence of this function means that the standard templated operator<<() 
+(defined in s32strm.h) is available to externalise objects of this class. 
+
+@param aStream Stream to which the vTodo or vEvent should be externalised. */
+	{
+	if (!iEntityName)
+		SetEntityNameL(KVersitVarTokenVEVENT);
+	CVersitParser::ExternalizeL(aStream);
+	}
+
+EXPORT_C CParserPropertyValue* CParserVCalEntity::MakePropertyValueL(const TUid& aPropertyUid,HBufC16*& aValue)
+// From CVersitParser
+	{
+	if(!aValue && !iLargeDataBuf)
+		return NULL;
+
+	switch (aPropertyUid.iUid)
+		{
+		case KVCalPropertyAlarmUid: // won't be recognized except by subclass
+			{
+			CVersitAlarm* alarm = MakePropertyValueAlarmL(aValue->Des());
+			CleanupStack::PushL(alarm);
+			CParserPropertyValue* value = new(ELeave) CParserPropertyValueAlarm(alarm);
+			CleanupStack::Pop(alarm);
+			return value;
+			}
+		case KVCalPropertyExtendedAlarmUid: // won't be recognized except by subclass
+			{
+			CVersitExtendedAlarm* richAlarm = NULL;
+			if (aValue)
+				{
+				richAlarm = MakePropertyValueExtendedAlarmL(aValue->Des());
+				}
+			else
+				{
+				richAlarm = MakePropertyValueExtendedAlarmL(*iLargeDataBuf);
+				}
+			CleanupStack::PushL(richAlarm);
+			CParserPropertyValue* value = new(ELeave) CParserPropertyValueExtendedAlarm(richAlarm);
+			CleanupStack::Pop(richAlarm);
+			return value;
+			}
+		case KVCalPropertyRecurrenceUid:
+			{
+			TPtr val=aValue->Des();
+			return MakePropertyValueRecurrenceL(val);
+			}
+		default:
+			break;
+		};
+	return CVersitParser::MakePropertyValueL(aPropertyUid,aValue);
+	}
+
+EXPORT_C CVersitAlarm* CParserVCalEntity::MakePropertyValueAlarmL(TPtr16 aAlarmValue)
+//Make an Alarm property from stream
+	{
+	TPtrC8 propName=iCurrentProperty->Name();
+	TPtr16 field(NULL,0);
+
+	FindFirstField(field,aAlarmValue);
+	TVersitDateTime* runTime=NULL;
+	if(field.Length()>0)
+		runTime = DecodeDateTimeL(field);
+	CleanupStack::PushL(runTime);
+	
+	FindFirstField(field,aAlarmValue);
+	TTime* snoozeTime = NULL;
+	if(field.Length()>0)
+		snoozeTime = DecodeTimePeriodL(field);
+	CleanupStack::PushL(snoozeTime);
+
+	FindFirstField(field,aAlarmValue);
+	TInt repeatCount=0;
+	if(field.Length()>0)
+		Val(field, repeatCount);
+
+	if (propName==KVersitTokenAALARM || propName==KVersitTokenMALARM)
+		FindFirstField(field,aAlarmValue);
+	else
+		field.Zero();
+	
+	TPtr16 note(NULL,0);
+	if (propName!=KVersitTokenAALARM)
+		FindFirstField(note,aAlarmValue);
+
+	CVersitAlarm* alarm = CVersitAlarm::NewL(runTime, snoozeTime, repeatCount, field, note);
+
+	CleanupStack::Pop(2,runTime);
+	return alarm; //alarm takes ownership of runTime and snoozeTime
+	}
+
+/** Create a new extended alarm from a stream.
+The MIME type is set to the creating object's MIME type.
+The disposition is set to the creating object's disposition.  
+@param aAlarmValue a pointer to a buffer containing the assocaited data for the alarm. Should not point to an empty 
+descriptor.
+@return The newly created extended alarm. */
+EXPORT_C CVersitExtendedAlarm* CParserVCalEntity::MakePropertyValueExtendedAlarmL(TPtr16 aAlarmValue)
+	{
+	TPtrC8 propName=iCurrentProperty->Name();
+	TPtr16 field(NULL,0);
+
+
+	// Note: the presence of this property means that
+	// the parameters VALUE and X-CONTENTTYPE should be present; if not
+	// present, then INLINE rich data shall be assumed
+
+	TPtrC8 mimeType(NULL,0);
+	TPtrC8 dispositionField(NULL,0);
+
+	// content-value-type assumes default is INLINE if parameter not present
+	CVersitExtendedAlarm::TDisposition disposition = CVersitExtendedAlarm::EDispositionInline;
+
+	// read in data content-type
+	CParserParam* alarmParameter = iCurrentProperty->Param(KVersitTokenCONTENTTYPE);
+
+	if (alarmParameter)
+		{
+		mimeType.Set(alarmParameter->Value());
+		}
+
+	// read in data content-value-type
+	alarmParameter = iCurrentProperty->Param(KVersitTokenVALUE);
+		
+	if (alarmParameter)
+		{
+		dispositionField.Set(alarmParameter->Value());
+		
+		// if there is a value, convert from text to enum
+		if (dispositionField.Length())
+			{
+			disposition = DecodeDisposition(dispositionField);
+			}
+		}
+		
+	FindRemainingField(field,aAlarmValue);
+	CVersitExtendedAlarm* alarm = CVersitExtendedAlarm::NewL(field.Collapse(), mimeType, disposition);
+
+	return alarm; 
+	}
+	
+/** Create a new extended alarm from a buffer.
+The MIME type is set to the creating object's MIME type.
+The disposition is set to the creating object's disposition. 
+@param aAlarmValue a reference to a buffer containing the assocaited data for the alarm. Should not be an empty 
+buffer.
+@return The newly created extended alarm. */	
+EXPORT_C CVersitExtendedAlarm* CParserVCalEntity::MakePropertyValueExtendedAlarmL(CBufSeg& aAlarmValue)
+	{
+	TPtrC8 propName=iCurrentProperty->Name();
+	TPtr16 field(NULL,0);
+
+
+	// Note: the presence of this property means that
+	// the parameters VALUE and CONTENTTYPE should be present; if not
+	// present, then MIME rich data shall be assumed
+
+	TPtrC8 mimeType(NULL,0);
+	TPtrC8 dispositionField(NULL,0);
+
+	// content-value-type assumes INLINE if parameter not present
+	CVersitExtendedAlarm::TDisposition disposition = CVersitExtendedAlarm::EDispositionInline;
+
+	// read in data content-type
+	CParserParam* alarmParameter = iCurrentProperty->Param(KVersitTokenCONTENTTYPE);
+
+	if (alarmParameter)
+		{
+		mimeType.Set(alarmParameter->Value());
+		}
+
+	// read in disposition
+	alarmParameter = iCurrentProperty->Param(KVersitTokenVALUE);
+		
+	if (alarmParameter)
+		{
+		dispositionField.Set(alarmParameter->Value());
+		
+		// if there is a value, convert from text to enum
+		if (dispositionField.Length())
+			{
+			disposition = DecodeDisposition(dispositionField);
+			}
+		}
+		
+	// read in rich data content
+	// For this version of MakePropertyValueExtendedAlarmL, we have the 
+	// data in a CBufSeg that should already have been decoded from BASE64
+	// (assuming everything else works properly). So we need to get it into 
+	// a TBufC8
+	TInt segSize = aAlarmValue.Size();
+	HBufC8* content = HBufC8::NewLC(segSize);
+	TPtr8 ptrContent(content->Des());
+	aAlarmValue.Read(0, ptrContent, segSize);
+	
+	CVersitExtendedAlarm* alarm = CVersitExtendedAlarm::NewL(ptrContent, mimeType, disposition);
+	CleanupStack::PopAndDestroy(content);
+	
+	return alarm; 
+	}
+
+/** Used to find the type of the content disposition: inline, URL, or unknown.
+Converts content-value-type token field to content-value-type enum.
+@param aContentDisposition The disposition of the data for the alarm action.
+@return decoded disposition type */
+EXPORT_C CVersitExtendedAlarm::TDisposition CParserVCalEntity::DecodeDisposition(const TDesC8& aContentDisposition) const
+	{
+	if (!aContentDisposition.CompareF(KVersitTokenINLINE))
+		{
+		return CVersitExtendedAlarm::EDispositionInline;
+		};
+		
+	if (!aContentDisposition.CompareF(KVersitTokenURL))
+		{
+		return CVersitExtendedAlarm::EDispositionUrl;
+		};
+	
+	return CVersitExtendedAlarm::EDispositionUnknown;
+	}
+
+
+/*
+ * Try to recognize aToken and return a UID for it. 
+ * Call <code>CVersitParser::RecognizeToken()</code>
+ * which recognizes generic Versit tokens if the token has not been 
+ * recognized in this function 
+ *
+ * @param     " const TDesC8& aToken "
+ *            The token to be recognized
+ * @return    " TUid "
+ *            a defined UID value if the token has been recognized, 
+ *				<code>KVersitTokenUnknownUid</code>, otherwise
+ */
+
+EXPORT_C TUid CParserVCalEntity::RecognizeToken(const TDesC8& aToken) const
+// From CVersitParser
+	{
+	TUid uid = KNullUid;
+	TChar firstChar(aToken.Ptr()[0]);
+	firstChar=firstChar.GetUpperCase();
+	switch (firstChar)
+		{
+	case 'A':	
+		if (!aToken.CompareF(KVersitTokenAALARM))
+			uid.iUid = KVCalPropertyAlarmUid;
+		else if (!aToken.CompareF(KVersitTokenATTENDEE))
+			uid.iUid = KVersitPropertyHBufCUid;
+		else if (!aToken.CompareF(KVersitTokenATTACH))
+			{
+			if(iCurrentProperty)
+				{//If it is internalising, iCurrentProperty is set
+				uid.iUid = KVersitPropertyBinaryUid;//In vCal standard, default value is binary
+				CParserParam* valueParam = iCurrentProperty->Param(KVersitTokenVALUE);
+				if (valueParam)
+					{
+					TPtrC8 pParameterValue(valueParam->Value());
+					
+					if (pParameterValue.CompareF(KVersitTokenINLINE) && pParameterValue.CompareF(KVersitTokenBINARY))
+						{//If VALUE isn't specified as INLINE or BINARY, value is text type.
+						uid.iUid = KVersitPropertyHBufCUid;			
+						}
+					}
+				}
+			}
+		break;
+	case 'C':
+		if (!aToken.CompareF(KVersitTokenCATEGORIES))
+			uid.iUid = KVersitPropertyCDesCArrayUid;
+		else if (!aToken.CompareF(KVersitTokenCLASS))
+			uid.iUid = KVersitPropertyHBufCUid;
+		else if (!aToken.CompareF(KVersitTokenCOMPLETED))
+			uid.iUid = KVersitPropertyDateTimeUid;
+		break;
+	case 'D':
+		if (!aToken.CompareF(KVersitTokenDALARM))
+			uid.iUid = KVCalPropertyAlarmUid;
+		else if (!aToken.CompareF(KVersitTokenDCREATED) ||
+				!aToken.CompareF(KVersitTokenDTEND) ||
+				!aToken.CompareF(KVersitTokenDTSTART) ||
+				!aToken.CompareF(KVersitTokenDUE))
+			uid.iUid = KVersitPropertyDateTimeUid;
+		else if(!aToken.CompareF(KVersitTokenDESCRIPTION))
+			uid.iUid = KVersitPropertyHBufCUid;
+		break;
+	case 'E':
+		if (!aToken.CompareF(KVersitTokenEXDATE))
+			uid.iUid = KVersitPropertyMultiDateTimeUid;
+		else if (!aToken.CompareF(KVersitTokenEXRULE))
+			uid.iUid = KVCalPropertyRecurrenceUid;
+		break;
+	case 'G':
+		if (!aToken.CompareF(KVersitTokenGEO))
+			uid.iUid = KVersitPropertyHBufCUid;
+		break;	
+	case 'L':
+		if (!aToken.CompareF(KVersitTokenLASTMODIFIED))
+			uid.iUid = KVersitPropertyDateTimeUid;
+		else if(!aToken.CompareF(KVersitTokenLOCATION))
+			uid.iUid = KVersitPropertyHBufCUid;
+		break;
+	case 'M':
+		if (!aToken.CompareF(KVersitTokenMALARM))
+			uid.iUid = KVCalPropertyAlarmUid;
+		break;
+	case 'P':
+		if (!aToken.CompareF(KVersitTokenPALARM))
+			uid.iUid = KVCalPropertyAlarmUid;
+		else if (!aToken.CompareF(KVersitTokenPRIORITY))
+			uid.iUid = KVersitPropertyIntUid;
+		break;
+	case 'R':
+		if(!aToken.CompareF(KVersitTokenRDATE))
+			uid.iUid = KVersitPropertyMultiDateTimeUid;
+		else if (!aToken.CompareF(KVersitTokenRELATEDTO))
+			uid.iUid = KVersitPropertyHBufCUid;
+		else if (!aToken.CompareF(KVersitTokenRESOURCES))
+			uid.iUid = KVersitPropertyCDesCArrayUid;
+		else if (!aToken.CompareF(KVersitTokenRNUM))
+			uid.iUid = KVersitPropertyIntUid;
+		else if (!aToken.CompareF(KVersitTokenRRULE))
+			uid.iUid = KVCalPropertyRecurrenceUid;
+		break;
+	case 'S':
+		if (!aToken.CompareF(KVersitTokenSEQUENCE))
+			uid.iUid = KVersitPropertyIntUid;
+		else if (!aToken.CompareF(KVersitTokenSTATUS) ||
+				!aToken.CompareF(KVersitTokenSUMMARY))
+			uid.iUid = KVersitPropertyHBufCUid;
+		break;
+	case 'T':
+		if(!aToken.CompareF(KVersitTokenTRANSP))
+			uid.iUid = KVersitPropertyIntUid;
+		break;
+	case 'U':
+		if (!aToken.CompareF(KVersitTokenURL) ||
+			!aToken.CompareF(KVersitTokenUID))
+		uid.iUid = KVersitPropertyHBufCUid;
+		break;
+	case 'X':
+		if (!aToken.CompareF(KVersitTokenXRECURRENCEID) ||
+			!aToken.CompareF(KVersitTokenXDTSTAMP))
+			{
+			uid.iUid = KVersitPropertyDateTimeUid;
+			}
+		else if (!aToken.CompareF(KVersitTokenXALARM))
+			{
+			uid.iUid = KVCalPropertyExtendedAlarmUid;
+			}
+		else if (!aToken.CompareF(KVersitTokenXLOCALUID))
+		    {
+			uid.iUid = KVersitPropertyIntUid;
+		    }
+		break;
+		}
+	if (uid == KNullUid)
+		return CVersitParser::RecognizeToken(aToken);
+	return uid;
+	}
+
+EXPORT_C void CParserVCalEntity::Reserved1()
+	{}
+
+EXPORT_C void CParserVCalEntity::Reserved2()
+	{}
+
+
+//
+// CVersitAlarm
+//
+
+CVersitAlarm::CVersitAlarm(TInt aRepeatCount)
+	: iRepeatCount(aRepeatCount)
+	{
+	}
+
+void CVersitAlarm::ConstructL(const TDesC& aAudioContent, const TDesC& aNote, TVersitDateTime* aRunTime, TTime* aSnoozeTime)
+	{
+	if (aAudioContent.Size())
+		{
+		iAudioContent = aAudioContent.AllocL();
+		}
+	if (aNote.Size())
+		{
+		iNote = aNote.AllocL();
+		}
+	iRunTime = aRunTime;
+	iSnoozeTime = aSnoozeTime;
+	}
+
+EXPORT_C CVersitAlarm* CVersitAlarm::NewL(TVersitDateTime* aRunTime, TTime* aSnoozeTime, TInt aRepeatCount, const TDesC& aAudioContent, const TDesC& aNote)
+/** Allocates and constructs a new alarm.
+
+Ownership of aRunTime and aSnoozeTime is taken in the end.
+
+@param aRunTime Pointer to the alarm time. 
+@param aSnoozeTime Pointer to the snooze time (may be NULL). 
+@param aRepeatCount The repeat count. 
+@param aAudioContent A binary buffer containing the sound data. May be an empty 
+descriptor. 
+@param aNote A descriptor containing text to display when the alarm is executing. 
+May be an empty descriptor. 
+@return Pointer to the newly created alarm. */
+	{
+	CVersitAlarm* self = new(ELeave) CVersitAlarm(aRepeatCount);
+	CleanupStack::PushL(self);
+	self->ConstructL(aAudioContent, aNote, aRunTime, aSnoozeTime);
+	CleanupStack::Pop(self);
+	return self;	
+	}
+
+EXPORT_C CVersitAlarm::~CVersitAlarm()
+/** Frees all resources owned by the alarm, prior to its destruction. */
+	{
+	delete iRunTime;
+	delete iSnoozeTime;
+	delete iAudioContent;
+	delete iNote;
+	}
+
+CVersitExtendedAlarm::CVersitExtendedAlarm()
+	{
+	}
+
+void CVersitExtendedAlarm::ConstructL(const TDesC8& aContent, const TDesC8& aContentMimeType, CVersitExtendedAlarm::TDisposition aContentDisposition) 
+	{
+	if (aContent.Size())
+		{
+		iContent = aContent.AllocL();		
+		}
+	else
+		{
+		iContent = NULL;
+		}
+		
+	if (aContentMimeType.Size())
+		{
+		iMimeType = aContentMimeType.AllocL();
+		}
+	else
+		{
+		iMimeType = NULL;
+		}
+	iDisposition = aContentDisposition;
+	}
+
+/** Allocates and constructs a new extended alarm (X-EPOCALARM).
+@param aContent A binary buffer containing the assocaited data for the alarm. Should not be empty 
+descriptor.
+@param aContentMimeType The MIME type of the data describing the action for the alarm.  
+@param aContentDisposition The disposition of the data for the alarm action.
+@return Pointer to the newly created extended alarm. */
+EXPORT_C CVersitExtendedAlarm* CVersitExtendedAlarm::NewL(const TDesC8& aContent, const TDesC8& aContentMimeType,
+						   			CVersitExtendedAlarm::TDisposition aContentDisposition)
+	{
+	CVersitExtendedAlarm * self = new(ELeave) CVersitExtendedAlarm();
+	CleanupStack::PushL(self);
+	self->ConstructL(aContent, aContentMimeType, aContentDisposition);
+	CleanupStack::Pop(self);
+	return self;	
+	}
+
+EXPORT_C CVersitExtendedAlarm::~CVersitExtendedAlarm()
+/** Frees all resources owned by the alarm, prior to its destruction. */
+	{
+	delete iContent;
+	delete iMimeType;
+	}
+
+//
+// CParserPropertyValueAlarm
+//
+EXPORT_C CParserPropertyValueAlarm::CParserPropertyValueAlarm(CVersitAlarm* aValue)
+: CParserTimePropertyValue(TUid::Uid(KVCalPropertyAlarmUid))
+	,iValue(aValue)
+/** Constructs a new alarm property value with a pointer to a CVersitAlarm.
+
+@param aValue Pointer to the alarm. The property value takes ownership of 
+the pointer. */
+	{}
+
+
+EXPORT_C CParserPropertyValueAlarm::~CParserPropertyValueAlarm()
+/** Frees all resources owned by the property value, prior to its destruction. */
+	{
+	delete iValue;
+	}
+
+EXPORT_C void CParserPropertyValueAlarm::ConvertAllDateTimesToUTCL(const TTimeIntervalSeconds& aIncrement, const CVersitDaylight* aDaylight)
+/** Converts the alarm time into universal time.
+
+The date/time of the alarm is checked against the daylight saving information 
+provided in aDaylight. If it falls inside the daylight saving period then 
+the daylight saving offset is subtracted from the time to convert it to universal 
+time. Otherwise aIncrement is added to the date/time of the alarm to convert 
+it to universal time.
+
+Note that the daylight savings offset will adjust the time both for the daylight 
+saving and for the time zone.
+
+The function has no effect if the value is already stored as universal time.
+
+If aDaylight is a NULL pointer then aIncrement is used.
+
+@param aIncrement A time interval in seconds which represents the negative 
+of the time zone of the originating machine. For instance, if the time zone 
+is +04:30, aIncrement should be set to -04:30.
+@param aDaylight Pointer to the specification for daylight saving. If the alarm's 
+time value is within the period for daylight saving, the value is modified 
+by the daylight saving offset (which accounts for both the time zone and daylight 
+saving rule). 
+@deprecated since 9.1
+*/
+	{
+	if (iValue && iValue->iRunTime && (iValue->iRunTime->iRelativeTime != TVersitDateTime::EIsUTC) && !iValue->iRunTime->IsFlagSet(TVersitDateTime::EExportLeaveAsLocalTime))
+		{
+		ConvertDateTime(&iValue->iRunTime->iDateTime,aIncrement, aDaylight);
+		iValue->iRunTime->iRelativeTime = TVersitDateTime::EIsUTC;		
+		}
+	}	
+
+EXPORT_C void CParserPropertyValueAlarm::ConvertAllUTCDateTimesToMachineLocalL(const TTimeIntervalSeconds& aIncrement)
+/** Converts the alarm time to machine-local time. 
+
+This involves adjusting the alarm's date/time by the offset in aIncrement.
+
+The function has no effect if the value is already stored as machine-local 
+time.
+
+@param aIncrement A time interval which represents the number of seconds which 
+is to be added to the date/time value. This should normally be the universal 
+time offset for the machine's locale. 
+@deprecated since 9.1
+*/
+	{
+	if (iValue && iValue->iRunTime && (iValue->iRunTime->iRelativeTime == TVersitDateTime::EIsUTC))
+		{
+		ConvertDateTime(&iValue->iRunTime->iDateTime, aIncrement,NULL);
+		iValue->iRunTime->iRelativeTime = TVersitDateTime::EIsMachineLocal;
+		}
+	}
+
+EXPORT_C void CParserPropertyValueAlarm::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& aEncodingCharset,TInt aLengthOutput)
+	// From CParserProperty
+/** Externalises the alarm property value into aStream.
+
+@param aStream Stream to which the value should be externalised.
+@param aEncodingCharset Contains the character set and encoding into which the 
+property value should be converted.
+@param aLengthOutput The amount of text that has been outputted on the line 
+so far, which needs to be taken into account when calculating if and where 
+any line break should occur. */
+	{
+	if (!iValue)
+		return;
+
+	TInt bufLen=64;		//This should cover the Date/Time, Duration, Repeat Count and semi colons
+	if (iValue->iAudioContent)
+		bufLen+=iValue->iAudioContent->Length();
+	if (iValue->iNote)
+		bufLen+=iValue->iNote->Length();
+	HBufC* outputStringBuf=HBufC::NewLC(bufLen);
+	TPtr outputString=outputStringBuf->Des();
+	TBuf8<KVersitDefaultBufferSize> buf;
+	if (iValue->iRunTime)
+		{
+		EncodeVersitDateTimeL(buf,*iValue->iRunTime);
+		Append(outputString,buf);
+		}
+	outputString.Append(KVersitTokenSemiColonUnicode);
+	if (iValue->iSnoozeTime)
+		{
+		EncodeTimePeriodL(buf,*iValue->iSnoozeTime);
+		Append(outputString,buf);
+		}
+	outputString.Append(KVersitTokenSemiColonUnicode);
+	__ASSERT_DEBUG(iValue->iRepeatCount < 100000, User::Invariant());
+	if(iValue->iRepeatCount>0)
+		{
+		outputString.AppendNum(iValue->iRepeatCount);
+		}
+	outputString.Append(KVersitTokenSemiColonUnicode);
+
+	if (iValue->iAudioContent)
+		{
+		outputString.Append(*iValue->iAudioContent);
+		if (iValue->iNote)
+			outputString.Append(KVersitTokenSemiColonUnicode);
+		}
+	if (iValue->iNote)
+		outputString.Append(*iValue->iNote);
+	FoldAndWriteValueToStreamL(aStream,outputString,aEncodingCharset,aLengthOutput);
+	CleanupStack::PopAndDestroy(outputStringBuf);
+	}
+
+EXPORT_C TBool CParserPropertyValueAlarm::IsAsciiCharacterSetSufficient()
+/** Tests whether the property value can be represented using the ASCII character 
+set.
+
+@return ETrue if the property value can be represented using the ASCII character 
+set. If not, EFalse. */
+	{
+	if	(!iValue)
+		return ETrue;
+	if (iValue->iAudioContent && !VersitUtils::DescriptorContainsOnlySevenBitCharacters(*iValue->iAudioContent))
+		return EFalse;
+	if (iValue->iNote && !VersitUtils::DescriptorContainsOnlySevenBitCharacters(*iValue->iNote))
+		return EFalse;
+	return ETrue;
+	}
+
+//
+// CParserPropertyValueExtendedAlarm. 
+//
+EXPORT_C CParserPropertyValueExtendedAlarm::CParserPropertyValueExtendedAlarm(CVersitExtendedAlarm* aValue)
+: CParserTimePropertyValue(TUid::Uid(KVCalPropertyExtendedAlarmUid))
+	,iValue(aValue)
+/** Constructs a new extended alarm property value with a pointer to a CVersitExtendedAlarm.
+
+@param aValue Pointer to the alarm. The property value takes ownership of 
+the pointer. */
+	{}
+
+EXPORT_C CParserPropertyValueExtendedAlarm::~CParserPropertyValueExtendedAlarm()
+/** Frees all resources owned by the property value, prior to its destruction. */
+	{
+	delete iValue;
+	}
+
+EXPORT_C void CParserPropertyValueExtendedAlarm::ConvertAllDateTimesToUTCL(const TTimeIntervalSeconds& /* aIncrement */, const CVersitDaylight* /* aDaylight */)
+/** Converts the extended alarm time into universal time.
+
+@param aIncrement A time interval in seconds which represents the negative 
+of the time zone of the originating machine. For instance, if the time zone 
+is +04:30, aIncrement should be set to -04:30.
+@param aDaylight Pointer to the specification for daylight saving. If the alarm's 
+time value is within the period for daylight saving, the value is modified 
+by the daylight saving offset (which accounts for both the time zone and daylight 
+saving rule). 
+@deprecated since 9.1
+*/
+	{
+	}	
+
+EXPORT_C void CParserPropertyValueExtendedAlarm::ConvertAllUTCDateTimesToMachineLocalL(const TTimeIntervalSeconds& /*aIncrement */)
+/** Converts the extended alarm time to machine-local time.
+
+@param aIncrement A time interval which represents the number of seconds which 
+is to be added to the date/time value. This should normally be the universal 
+time offset for the machine's locale. 
+@deprecated since 9.1
+*/
+	{
+	}
+
+EXPORT_C void CParserPropertyValueExtendedAlarm::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& aEncodingCharset,TInt aLengthOutput)
+// From CParserProperty
+/** Externalises the extended alarm property value into aStream.
+
+@param aStream Stream to which the value should be externalised.
+@param aEncodingCharset Contains the character set and encoding into which the 
+property value should be converted.
+@param aLengthOutput The amount of text that has been outputted on the line 
+so far, which needs to be taken into account when calculating if and where 
+any line break should occur. */
+	{
+	if (!iValue)
+		{
+		return;
+		}
+	// There are two encoding possibilities for this value. If it is a URL, then we expand the 8 bit string,
+	// which we know is US ASCII into Unicode and append it. If it is INLINE data, then we must encode it as 
+	// 64 bit data
+	switch (iValue->iDisposition)
+		{
+		case CVersitExtendedAlarm::EDispositionUrl:
+			ExternalizeUrlL(aStream, aEncodingCharset, aLengthOutput);
+			break;
+		case CVersitExtendedAlarm::EDispositionInline:
+		default:  //intentional fall through, we'll treat any unknown as INLINE data
+			ExternalizeInlineL(aStream, aEncodingCharset, aLengthOutput);
+			break;
+		}
+	
+	}
+
+void CParserPropertyValueExtendedAlarm::ExternalizeUrlL(RWriteStream& aStream,const Versit::TEncodingAndCharset& aEncodingCharset,TInt aLengthOutput)
+	{
+	TInt bufLen = 0;
+	if (iValue->iContent)
+		{
+		bufLen+=iValue->iContent->Size();		
+		}
+	
+	HBufC* outputStringBuf=HBufC::NewLC(bufLen);
+
+	TPtr outputString=outputStringBuf->Des();
+		
+	HBufC* bufferUrl = NULL;
+
+	CVersitUnicodeUtils* vUtils = new(ELeave)CVersitUnicodeUtils();
+	vUtils->CreateConverterL();
+
+	bufferUrl = vUtils->WidenL(*(iValue->iContent));
+
+	TPtrC desUrl(bufferUrl->Des());
+	CleanupStack::PushL(bufferUrl);
+
+	outputString.Append(desUrl);
+
+	FoldAndWriteValueToStreamL(aStream,outputString,aEncodingCharset,aLengthOutput);
+	
+	CleanupStack::PopAndDestroy(2,outputStringBuf);
+	
+	}
+
+const TInt KBase64MaxLineLength = 64; // chars
+
+void CParserPropertyValueExtendedAlarm::ExternalizeInlineL(RWriteStream& aStream,const Versit::TEncodingAndCharset& /*aEncodingCharset*/,TInt /*aLengthOutput*/)
+	{
+	if (iValue->iContent)
+		{
+		const TInt length = iValue->iContent->Size();
+		if (length >0)
+			{
+			CBufSeg* target = CBufSeg::NewL(length);
+			CleanupStack::PushL(target);
+
+			//get the Data Content into a usable buffer
+			CBufSeg* source = CBufSeg::NewL(length+1);
+			source->Reset();
+			source->InsertL(0, *(iValue->iContent));
+			source->Compress();
+			CleanupStack::PushL(source);
+
+			
+			//Do the BASE64 Encoding
+			RBufReadStream readStream;
+			readStream.Open(*source);
+			VersitUtils::ConArcEncodeL(readStream, *target, 
+						VersitUtils::ConArcEncodingUid(Versit::EBase64Encoding));
+			readStream.Close();
+
+			// make sure the  line lengths are appropriate
+			VersitUtils::WrapLinesL(*target, KBase64MaxLineLength);
+
+			// write to output stream
+			TInt pos=0;
+			TInt len=target->Size();
+			while (pos < len)
+				{
+				TPtr8 ptr = target->Ptr(pos);
+				aStream.WriteL(ptr);
+				pos+=ptr.Length();
+				}
+			CleanupStack::PopAndDestroy(2, target);
+			}
+		}
+	aStream.WriteL(KVersitTokenCRLF);
+	}
+
+	
+EXPORT_C TBool CParserPropertyValueExtendedAlarm::IsAsciiCharacterSetSufficient()
+/** Tests whether the property value can be represented using the ASCII character 
+set.
+
+@return ETrue if the property value can be represented using the ASCII character 
+set. If not, EFalse. */
+	{
+	if (!iValue)
+		{
+		return ETrue;
+		}
+	
+	if (!iValue->iContent)
+		{
+		return ETrue;
+		}
+	
+	if (iValue->iDisposition == CVersitExtendedAlarm::EDispositionUrl)
+		{
+		return ETrue;
+		}
+		
+	return EFalse;
+	}
+