pimappservices/calendar/server/src/agsfileconverter.cpp
changeset 0 f979ecb2b13e
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     1 // Copyright (c) 2006-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 "agsfileconverter.h"
       
    17 
       
    18 #include <s32file.h>
       
    19 #include <apparc.h>
       
    20 #include <asshddefs.h>
       
    21 #include <txtrich.h>
       
    22 #include <vtzrules.h>
       
    23 
       
    24 #include "agscategorylist.h"
       
    25 #include "agsentrymanager.h"
       
    26 #include "agmcontent.h"
       
    27 #include "agmdate.h"
       
    28 #include "agmentry.h"
       
    29 #include "agsentrymodel.h"
       
    30 #include "agsstreamidset.h"
       
    31 #include "agmutil.h"
       
    32 #include "agsver.h"
       
    33 #include "agmcategory.h"
       
    34 #include "agmattendee.h"
       
    35 #include "agsfilemanager.h"
       
    36 #include "agsmain.h"
       
    37 #include "calcommonimpl.h"
       
    38 #include "agstzruleindex.h"
       
    39 
       
    40 const TInt KMajorVersionNumber = 1;
       
    41 const TInt KMinorVersionNumber = 2;
       
    42 
       
    43 const TInt KBuildNumber = 2;	// Build 1.2.2 is current build
       
    44 const TInt KBuildCompatibleVersion = 1;
       
    45 //
       
    46 const TInt KOldMinorVersionNumber = 1;
       
    47 const TInt KOldBuildV94 = 211;		// build 1.1.211 is v9.4 compacted version
       
    48 const TInt KOldBuildV92 = 210;		// build 1.1.210 is v9.2
       
    49 const TInt KOldBuildV91 = 209;		// build 1.1.209 is v9.1
       
    50 									// build 1.1.208 is v8.0 and v8.1
       
    51 									// build 1.1.207 is 6.0 & 6.1 (prior builds 204-206 were dev releases)
       
    52 
       
    53 // ---------------------------- CalFileVersionUtils -------------------------
       
    54 
       
    55 CAgnCalendarConverter* CalFileVersionUtils::CreateConverterL(const TAgnVersion& aFileVersion, CAgnServFile& aAgnServerFile)
       
    56 /** @internalComponent */
       
    57 	{
       
    58 	CAgnCalendarConverter* converter = NULL;
       
    59 	
       
    60 	if (aFileVersion == TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV91))) 
       
    61 		{
       
    62 		// file format 1.1.209 used in 9.1
       
    63 		converter = CAgnCalendarConverter209::NewL(aAgnServerFile);
       
    64 		}
       
    65 	else if (aFileVersion == TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV92))) 
       
    66 		{
       
    67 		// file format 1.1.210 used in 9.2
       
    68 		converter = CAgnCalendarConverter210::NewL(aAgnServerFile);
       
    69 		}
       
    70 	else if (aFileVersion == TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV94)))
       
    71 		{
       
    72 		// file format 1.1.211 used in 9.4 compacted file version
       
    73 		converter = CAgnCalendarConverter211::NewL(aAgnServerFile);
       
    74 		}
       
    75 	else if (aFileVersion == CurrentFileVersion() )
       
    76 		{
       
    77 		converter = NULL;
       
    78 		}
       
    79 	else
       
    80 		{
       
    81 		User::Leave(KErrNotSupported);
       
    82 		}
       
    83 	
       
    84 	return converter;
       
    85 	}
       
    86 
       
    87 void CalFileVersionUtils::FileVersionSupportedL(const TAgnVersion& aFileVersion, CalCommon::TCalFileVersionSupport& aStatus)
       
    88 	{
       
    89 	if ( aFileVersion == CurrentFileVersion() ||
       
    90 			aFileVersion == TAgnVersion(TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildCompatibleVersion)))
       
    91 		{
       
    92 		// The the file was created by an agenda model
       
    93 		// of the current version
       
    94 		//
       
    95 		aStatus = CalCommon::EFileIsCurrentVersion;
       
    96 		}
       
    97 	else
       
    98 		{
       
    99 		RArray<TAgnVersion> supportedFileVersions;
       
   100 		CleanupClosePushL(supportedFileVersions);
       
   101 		supportedFileVersions.AppendL(TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV94)));
       
   102 		supportedFileVersions.AppendL(TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV92)));
       
   103 		supportedFileVersions.AppendL(TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV91)));
       
   104 		
       
   105 		// The file version is not current but if it is in the 
       
   106 		// list of versions supported by this agenda model it can
       
   107 		// be converted to current version.
       
   108 		//
       
   109 		aStatus = CalCommon::EUnsupportedFileVersion;
       
   110 		for ( TInt i = 0; i < supportedFileVersions.Count(); ++i )
       
   111 			{
       
   112 			if ( supportedFileVersions[i] == aFileVersion )
       
   113 				{
       
   114 				aStatus = CalCommon::EFileNeedsConverting;
       
   115 				break;
       
   116 				}
       
   117 			}
       
   118 		CleanupStack::PopAndDestroy(&supportedFileVersions);
       
   119 		}
       
   120 	}
       
   121 
       
   122 TAgnVersion CalFileVersionUtils::CurrentFileVersion()
       
   123 	{ 
       
   124 	return (TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildNumber));
       
   125 	}
       
   126 
       
   127 // ---------------------------- CAgnCalendarConverter -------------------------
       
   128 
       
   129 CAgnCalendarConverter::CAgnCalendarConverter()
       
   130 	{
       
   131 	}
       
   132 	
       
   133 CAgnCalendarConverter::~CAgnCalendarConverter()
       
   134 /** @internalComponent */
       
   135 	{
       
   136 	if(iOutputTzRuleIndex)
       
   137 		{
       
   138 		delete iOutputTzRuleIndex; 
       
   139 		}
       
   140 	
       
   141 	delete iDictionary;
       
   142 	delete iOutputStreamStore;
       
   143 	delete iOutModelStreamIdSet;
       
   144 	delete iOutEntryManager;
       
   145 	}
       
   146 
       
   147 void CAgnCalendarConverter::ConstructL(CAgnServFile& aAgnServerFile)
       
   148 /** @internalComponent */
       
   149 	{ 
       
   150 	iOutModelStreamIdSet = CAgnModelStreamIdSet::NewL();
       
   151 	iOutEntryManager = CAgnEntryManager::NewL();
       
   152 	iAgnServerFile = &aAgnServerFile;
       
   153 	
       
   154 	// Get the original (old version) stream store from the CAgnServFile
       
   155 	//
       
   156 	iInputStreamStore = iAgnServerFile->StoreL();
       
   157 	__ASSERT_ALWAYS(iInputStreamStore, User::Leave(KErrCorrupt));
       
   158 	
       
   159 	// Create the output stream store
       
   160 	//
       
   161 	TParsePtrC fullFileName(iAgnServerFile->FileName());
       
   162 	HBufC* fileName = HBufC::NewLC(fullFileName.Drive().Length() + 
       
   163 								   fullFileName.NameAndExt().Length() +
       
   164 								   KUpdatedAgendaFileExtension().Length());
       
   165 	TPtr fileNamePtr(fileName->Des());
       
   166 	fileNamePtr.Append(fullFileName.Drive());
       
   167 	fileNamePtr.Append(fullFileName.NameAndExt());
       
   168 	fileNamePtr.Append(KUpdatedAgendaFileExtension);
       
   169 	
       
   170 	// Create the output stream store where converted information will be kept
       
   171 	// This code copied from CAgnServerSession::CreateAgendaFileL() and CAgnEntryModel::CreateL(CStreamStore& aStore)
       
   172 	//
       
   173 	iOutputStreamStore = iAgnServerFile->Server().FileMgr()->CreateAgendaFileLC(fileNamePtr);
       
   174 	CleanupStack::Pop(iOutputStreamStore);
       
   175 	CleanupStack::PopAndDestroy(fileName);
       
   176 	iOutputStreamStore->SetTypeL(TUidType(KPermanentFileStoreLayoutUid, KUidAppDllDoc, KUidAgnApp));
       
   177 	
       
   178     iOutEntryManager->SetStore(*iOutputStreamStore);
       
   179         
       
   180 	// Create the network of stream Ids needed by the model
       
   181 	TStreamId headstreamId = iOutModelStreamIdSet->CreateL(*iOutputStreamStore, CalFileVersionUtils::CurrentFileVersion());
       
   182 	
       
   183 	// Create the stream dictionary for iOutputStreamStore and keep headstreamId in it
       
   184 	//
       
   185 	iDictionary = CStreamDictionary::NewL();
       
   186 	iDictionary->AssignL(KUidAgnModel, headstreamId);
       
   187 	
       
   188     // Set stream dictionary in stream store
       
   189 	TApaAppIdentifier dummyApp(KUidAgnModel, KNullDesC());
       
   190 	CApaProcess::WriteRootStreamL(*iOutputStreamStore,*iDictionary, dummyApp);
       
   191 	
       
   192 	iOutputTzRuleIndex = CAgnTzRuleIndex::NewL(*iDictionary, *iOutputStreamStore);
       
   193 	}
       
   194 
       
   195 CFileStore& CAgnCalendarConverter::InputStreamStore() const
       
   196 	{
       
   197 	return *iInputStreamStore;
       
   198 	}
       
   199 
       
   200 CFileStore& CAgnCalendarConverter::OutputStreamStore() const
       
   201 	{
       
   202 	return *iOutputStreamStore;
       
   203 	}
       
   204 
       
   205 CAgnServFile& CAgnCalendarConverter::AgnServerFile() const
       
   206 	{
       
   207 	return *iAgnServerFile;
       
   208 	}
       
   209 
       
   210 CStreamDictionary& CAgnCalendarConverter::Dictionary() const
       
   211 	{
       
   212 	return *iDictionary;
       
   213 	}
       
   214 
       
   215 void CAgnCalendarConverter::AddToIndexL(CAgnEntry& aEntry) const
       
   216 	{
       
   217 	iAgnServerFile->Model()->UpdateIndexL(aEntry, NULL, CAgnEntryModel::EAdd);
       
   218 	}
       
   219 
       
   220 void CAgnCalendarConverter::SetNextLocalUidValue(TInt aValue) const
       
   221 	{
       
   222 	iAgnServerFile->Model()->iNextLocalUidValue = aValue;
       
   223 	}
       
   224 
       
   225 void CAgnCalendarConverter::SetModelStreamIds(const TAgnVersion& aVersion,
       
   226 											  const TStreamId& aEntrySetStreamId,
       
   227 											  const TStreamId& aNextLocalUidValueStreamId,
       
   228 											  const TStreamId& aEntryManagerStreamId,
       
   229 											  const TStreamId& aFileInformationStreamId,
       
   230 											  CAgnModelStreamIdSet& aModelStreamIdSet) const
       
   231 	{
       
   232 	aModelStreamIdSet.iVersion = aVersion;
       
   233 	aModelStreamIdSet.iEntrySetStreamId = aEntrySetStreamId;
       
   234 	aModelStreamIdSet.iNextLocalUidValueStreamId = aNextLocalUidValueStreamId;
       
   235 	aModelStreamIdSet.iEntryManagerStreamId = aEntryManagerStreamId;
       
   236 	aModelStreamIdSet.iFileInformationStreamId = aFileInformationStreamId;
       
   237 	}
       
   238 						   
       
   239 /**
       
   240 This method is executed as the last step of a calendar file conversion.
       
   241 Externalizes to the new file store the new CAgnEntryManager and CAgnModelStreamIdSet.
       
   242 Calls ReplaceAgendaFile() to update the Model and its ServerFile with the products of the
       
   243 conversion.
       
   244 @internalComponent */
       
   245 void CAgnCalendarConverter::CompleteConversionL()
       
   246 	{
       
   247 	// Copy iFileId and iNextUniqueIdValue to the Converter's output stream store
       
   248 	//
       
   249 	iAgnServerFile->Model()->ExternalizeFileIdL(*iOutputStreamStore, iOutModelStreamIdSet->FileInformationStreamId());
       
   250 	iAgnServerFile->Model()->ExternalizeNextUidValuesL(*iOutputStreamStore, iOutModelStreamIdSet->NextLocalUidValueStreamId());
       
   251 	iOutputStreamStore->CommitL();
       
   252 
       
   253 	// Commit the streamIdSet and the EntryManager to the output store
       
   254 	//
       
   255 	RStoreWriteStream stream;
       
   256 	stream.ReplaceLC(*iOutputStreamStore,iOutModelStreamIdSet->EntryManagerStreamId());
       
   257 	stream << *iOutEntryManager;
       
   258 	stream.CommitL();
       
   259 	CleanupStack::PopAndDestroy();
       
   260 	
       
   261 	iOutModelStreamIdSet->CommitL(*iOutputStreamStore);
       
   262 	iOutputStreamStore->CommitL();
       
   263 	
       
   264 	delete iDictionary;
       
   265 	iDictionary = NULL;
       
   266 	delete iOutputStreamStore;
       
   267 	iOutputStreamStore = NULL;
       
   268 	
       
   269 	// Set new calendar file and dictionary in CAgnServFile
       
   270 	// (this deletes the old file, and hands over the ownership of iOutputTzRuleIndex)
       
   271 	//
       
   272 	iAgnServerFile->ReplaceConvertedAgendaFileL(*iOutEntryManager, *iOutputTzRuleIndex);
       
   273 	iOutputTzRuleIndex = NULL;
       
   274 	}
       
   275 	
       
   276 /**
       
   277 This method stores in CAgnCalendarConverter::iOutputStreamStore the entry that has been internalized
       
   278 from an old version file. 
       
   279 
       
   280 The persistence layer objects owned by the CAgnCalendarConverter (iOutEntryManager and iOutModelStreamIdSet)
       
   281 will also be updated to register the new entry.
       
   282 @internalComponent */
       
   283 void CAgnCalendarConverter::SaveRestoredEntryL(CAgnEntry& aEntry) const
       
   284 	{
       
   285 	
       
   286 	// Externalize outline attributes first
       
   287 	TStreamId id = KNullStreamId;
       
   288 	RStoreWriteStream out;
       
   289 	
       
   290 	id = WriteDescriptorToStreamL(aEntry.Description());
       
   291 	aEntry.SetDescriptionStreamId(id);
       
   292 	
       
   293 	id = WriteDescriptorToStreamL(aEntry.Summary());
       
   294 	aEntry.SetSummaryStreamId(id);
       
   295 	
       
   296 	if(aEntry.AlarmAction())
       
   297 		{
       
   298 		RStoreWriteStream out;
       
   299 		id = out.CreateLC(*iOutputStreamStore);
       
   300 		out << *aEntry.AlarmAction();
       
   301 		out.CommitL();
       
   302 		CleanupStack::PopAndDestroy(); //out
       
   303 		aEntry.SetAlarmActionStreamId(id);
       
   304 		}
       
   305 
       
   306 	iOutputTzRuleIndex->AddTzRuleL(aEntry);
       
   307 	TStreamId newStreamId = iOutEntryManager->AddEntryL(aEntry); // This changes the entry/instance ID
       
   308 
       
   309 	if (newStreamId != KNullStreamId)
       
   310 		{
       
   311 		// This puts the stream id in the array but doesn't commit it
       
   312 		// To reduce file acces, the ModelStreamIdSet is only commited when all
       
   313 		// the entries have been converted.
       
   314 		iOutModelStreamIdSet->EntryStreamIdSet().AddL(newStreamId);
       
   315 		}
       
   316 	}
       
   317 
       
   318 TStreamId CAgnCalendarConverter::WriteDescriptorToStreamL(const TDesC& aString) const
       
   319 /** @internalComponent */
       
   320 	{
       
   321 	if (aString.Length() > 0)
       
   322 		{
       
   323 		RStoreWriteStream out;
       
   324 		TStreamId id = out.CreateLC(*iOutputStreamStore);
       
   325 		out.WriteUint32L(aString.Length());
       
   326 		out << aString;
       
   327 		out.CommitL();
       
   328 		CleanupStack::PopAndDestroy(); //out
       
   329 		return id;
       
   330 		}
       
   331 	return KNullStreamId;
       
   332 	}
       
   333 	
       
   334 // CAgnCalendarConverter209 //
       
   335 
       
   336 CAgnCalendarConverter209::CAgnCalendarConverter209()
       
   337 	{
       
   338 	}
       
   339 	
       
   340 CAgnCalendarConverter209* CAgnCalendarConverter209::NewL(CAgnServFile& aAgnServerFile)
       
   341 	{
       
   342 	CAgnCalendarConverter209* converter = new (ELeave) CAgnCalendarConverter209();
       
   343 	CleanupStack::PushL(converter);
       
   344 	converter->ConstructL(aAgnServerFile);
       
   345 	CleanupStack::Pop(converter);
       
   346 	return converter;
       
   347 	}
       
   348 	
       
   349 void CAgnCalendarConverter209::InternalizeEntriesL(RReadStream& aStream)
       
   350 /** @internalComponent */
       
   351 	{
       
   352 	// The layout of the calendar file in 1.1.x puts a set of calendar entries first, followed by their 
       
   353 	// extended data. For this reason, the entire set must be loaded into memory before they can be stored.
       
   354 	RPointerArray<CAgnEntry> entryArray(TAgnEntryId::EMaxNumEntriesPerStream);
       
   355 	CleanupResetAndDestroyPushL(entryArray);
       
   356 	
       
   357 	RArray<TBool> isExtendedArray;
       
   358 	CleanupClosePushL(isExtendedArray);
       
   359 	
       
   360 	const TUint8 KCount = aStream.ReadUint8L();
       
   361 	for ( TInt ii = 0; ii < KCount; ++ii )
       
   362 		{
       
   363 		// Read in entries
       
   364 		TBool isExtended = EFalse;
       
   365 		CAgnEntry* entry = InternalizeEntryL(aStream, isExtended);
       
   366 		CleanupStack::PushL(entry);
       
   367 		entryArray.AppendL(entry);
       
   368 		CleanupStack::Pop(entry);
       
   369 		
       
   370 		isExtendedArray.AppendL(isExtended); // isExtended is set to ETrue if the entry has extended data (to be loaded later)
       
   371 		}
       
   372 	
       
   373 	for ( TInt i = 0; i < KCount; ++i )
       
   374 		{
       
   375 		// Now read in the extended attributes if necessary
       
   376 		if (isExtendedArray[i])
       
   377 			{
       
   378 			InternalizeExtendedEntryL(aStream, *entryArray[i]);
       
   379 			}
       
   380 
       
   381 		// The old aEntry has been internalized, so add it to the current version of the file
       
   382 	    SaveRestoredEntryL(*entryArray[i]);
       
   383 	    
       
   384 	    // add this entry to the index
       
   385 	    AddToIndexL(*entryArray[i]);
       
   386 		}
       
   387 
       
   388 	CleanupStack::PopAndDestroy(&isExtendedArray);
       
   389 	CleanupStack::PopAndDestroy(&entryArray);
       
   390 	}
       
   391 
       
   392 void CAgnCalendarConverter209::InternalizeNextUidValuesL(RReadStream& aStream)
       
   393 	{
       
   394 	SetNextLocalUidValue(aStream.ReadUint32L());
       
   395 	}
       
   396 
       
   397 /**
       
   398 This method internalizes the CAgnModelStreamIdSet according to the file version.
       
   399 It also copies to the Converter's own stream store the contents of 
       
   400 aModelStreamIdSet's streams that must be preserved
       
   401 during the conversion: iNextUniqueIdValue and iFileId.
       
   402 
       
   403 (Currently, it works for both 9.1 and 9.2 to 9.3)
       
   404 @internalComponent */
       
   405 void CAgnCalendarConverter209::InternalizeModelStreamIdSetL(RReadStream& aStream, CAgnModelStreamIdSet& aModelStreamIdSet)
       
   406 	{
       
   407 	// 9.2/9.1 was:                                     9.3 is:
       
   408 	// iVersion                                         iVersion
       
   409 	// iTodoListListStreamId
       
   410 	// iDeletedTodoListListStreamId
       
   411 	// iEntrySetStreamId                                iEntrySetStreamId
       
   412 	// iFormatLayerStreamId
       
   413 	// iNextLocalUidValueStreamId                       iNextLocalUidValueStreamId
       
   414 	// iObserverControllerStreamId
       
   415 	// iLastSynchronizedDateStreamId
       
   416 	// iEntryStoreStreamId                              iEntryManagerStreamId
       
   417 	// iFileInformationStreamId                         iFileInformationStreamId
       
   418 		
       
   419 	// Get the 9.1/9.2 bytes. Those that exit in 9.3, set them in the CAgnModelStreamIdSet.
       
   420 	// Skip the rest.
       
   421 	TStreamId disposableStreamId;
       
   422 	
       
   423 	TAgnVersion version;
       
   424 	aStream >> version;
       
   425 	
       
   426 	//Skip: iTodoListStreamId, iDeletedTodoListListStreamId
       
   427 	aStream >> disposableStreamId;
       
   428 	aStream >> disposableStreamId;
       
   429 	
       
   430 	TStreamId entrySetStreamId;
       
   431 	aStream >> entrySetStreamId;
       
   432 	
       
   433 	//Skip: iFormatLayerStreamId
       
   434 	aStream >> disposableStreamId;
       
   435 	
       
   436 	TStreamId nextLocalUidValueStreamId;
       
   437 	aStream >> nextLocalUidValueStreamId;
       
   438 	
       
   439 	//Skip: iObserverControllerStreamId, iLastSynchronizedDateStreamId;
       
   440 	aStream >> disposableStreamId;
       
   441 	aStream >> disposableStreamId;
       
   442 	
       
   443 	TStreamId entryManagerStreamId;
       
   444 	aStream >> entryManagerStreamId;
       
   445 	
       
   446 	TStreamId fileInformationStreamId;
       
   447 	aStream >> fileInformationStreamId;
       
   448 	
       
   449 	SetModelStreamIds(version, entrySetStreamId, nextLocalUidValueStreamId, entryManagerStreamId, fileInformationStreamId, aModelStreamIdSet);
       
   450 	}
       
   451 
       
   452 /**
       
   453 Categories have not changed from 9.1 to 9.3.
       
   454 Just copy them from the original file to the new file.
       
   455 
       
   456 @internalComponent */
       
   457 void CAgnCalendarConverter209::InternalizeCategoriesL()
       
   458 	{
       
   459 	TStreamId streamId = AgnServerFile().WriteCategoryListL(OutputStreamStore());
       
   460 	AgnServerFile().AddStreamToDictionaryL(KUidAgnCategoryList, streamId, Dictionary(), OutputStreamStore());
       
   461 	}
       
   462 
       
   463 CAgnEntry* CAgnCalendarConverter209::InternalizeEntryL(RReadStream& aStream, TBool& aHasExtended)
       
   464 	{
       
   465 	enum TAgnEntryTypeV9192 // the entry type enumeration in v9.1 and v9.2
       
   466 		{
       
   467 		EAgnAppt,
       
   468 		EAgnTodo,
       
   469 		EAgnEvent,
       
   470 		EAgnAnniv
       
   471 		};
       
   472 	
       
   473 	const TInt KAgnExtendedDataFlag = 0x80;
       
   474     // Remove 9.1's/9.2's KAgnExtendedDataFlag (0x80)
       
   475     // from the entry type
       
   476     //
       
   477     TUint8 typeData = aStream.ReadUint8L();
       
   478     
       
   479 	if (typeData & KAgnExtendedDataFlag)
       
   480 		{
       
   481 		const TUint8 KVersion = aStream.ReadUint8L();
       
   482 		__ASSERT_ALWAYS(KVersion !=0, User::Leave(KErrCorrupt));  //version mumbers started from 1
       
   483 		if (KVersion > 1)
       
   484 			{
       
   485 			const TUint8 KLength = aStream.ReadUint8L();
       
   486 			for (TInt i=0; i<KLength; ++i)
       
   487 				{
       
   488 				aStream.ReadUint8L(); //skip additional data becouse we don't support it yet
       
   489 				}
       
   490 			}
       
   491 		typeData &= ~KAgnExtendedDataFlag;
       
   492 		}
       
   493 		
       
   494 	const TAgnEntryTypeV9192 KV9192Type = static_cast<TAgnEntryTypeV9192>(typeData);
       
   495 	
       
   496 	CCalEntry::TType entryType = CCalEntry::EAppt;
       
   497 
       
   498 	TAgnEntryId entryId;
       
   499 	entryId.InternalizeL(aStream); //TUInt32 iId
       
   500 	TUint16 attributes = aStream.ReadUint16L(); 
       
   501 	
       
   502 	switch (KV9192Type)
       
   503 		{
       
   504 		case EAgnAppt:
       
   505 			if (attributes & EBit9)
       
   506 				{
       
   507 				entryType = CCalEntry::EReminder; // is a day note
       
   508 				}
       
   509 			else
       
   510 				{
       
   511 				entryType = CCalEntry::EAppt;
       
   512 				}
       
   513 			break;
       
   514 		case EAgnAnniv:
       
   515 			entryType = CCalEntry::EAnniv;
       
   516 			break;
       
   517 		case EAgnEvent:
       
   518 			entryType = CCalEntry::EEvent;
       
   519 			break;
       
   520 		case EAgnTodo:
       
   521 			entryType = CCalEntry::ETodo;
       
   522 			break;
       
   523 		default:
       
   524 			User::Leave(KErrCorrupt);
       
   525 		}
       
   526 	
       
   527     if (attributes & EBit13)
       
   528     	{
       
   529     	aHasExtended = ETrue;
       
   530     	}
       
   531     else
       
   532     	{
       
   533     	aHasExtended = EFalse;
       
   534     	}
       
   535     	
       
   536     CCalEntry::TStatus status = CCalEntry::ENullStatus;
       
   537     // Get status from attributes' bits 
       
   538     //
       
   539     if (attributes & (EBit14 | EBit15 | EBit16))
       
   540     	{
       
   541     	// Bits 14,15,16 on.
       
   542     	status = CCalEntry::EVCalDelegated;
       
   543     	}
       
   544     else if (attributes & (EBit14 | EBit15))
       
   545     	{
       
   546     	// Bits 14, 15 on
       
   547     	if (entryType == CCalEntry::ETodo)
       
   548     		{
       
   549     		status = CCalEntry::ETodoCompleted;
       
   550     		}
       
   551     	}
       
   552     else if (attributes & (EBit14 | EBit16))
       
   553     	{
       
   554     	//Bits 14,16 on
       
   555     	status = CCalEntry::EVCalDeclined;
       
   556     	}
       
   557     else if (attributes & (EBit15 | EBit16))
       
   558     	{
       
   559     	// Bits 15, 16 on
       
   560     	status = CCalEntry::EVCalSent;
       
   561     	}
       
   562     else if (attributes & EBit14)
       
   563    	 	{
       
   564     	if (entryType != CCalEntry::ETodo)
       
   565     		{
       
   566     		status = CCalEntry::EConfirmed;
       
   567     		}
       
   568    	 	}
       
   569     else if (attributes & EBit15)
       
   570     	{
       
   571     	status = CCalEntry::EVCalNeedsAction;
       
   572     	}
       
   573     else if (attributes & EBit16)
       
   574     	{
       
   575     	status = CCalEntry::EVCalAccepted;
       
   576     	}
       
   577     else if(attributes & EBit11)
       
   578     	{
       
   579     	if (entryType != CCalEntry::ETodo)
       
   580     		{
       
   581     		status = CCalEntry::ETentative;
       
   582     		}
       
   583     	}
       
   584  
       
   585     // read GS data
       
   586    	enum TGsTypeV9192
       
   587 		{
       
   588 		/** Not a GS Entry (created using AgnModel APIs directly, not CalInterimAPI. */
       
   589 		ENonGsEntry,
       
   590 		/** Parent Entry. */
       
   591 		EGsRootParent,
       
   592 		/** Not used. */
       
   593 		EGsParent,
       
   594 		/** Child Entry. */
       
   595 		EGsLeaf
       
   596 		};
       
   597 			
       
   598 	CAgnEntry* entry = NULL;
       
   599 	
       
   600 	const TGsTypeV9192 KCalTypeV9192 = static_cast<TGsTypeV9192> (aStream.ReadInt8L());
       
   601 	switch (KCalTypeV9192)
       
   602 		{
       
   603 		case EGsRootParent:
       
   604 			{
       
   605 		    aStream.ReadUint32L(); // ignore guid hash
       
   606 		    HBufC8* guid = HBufC8::NewLC(aStream, KAgnEntryMaxGuidLength);   
       
   607 		    
       
   608 		    aStream.ReadInt8L(); // read other class type 
       
   609 		    
       
   610 		    entry = CAgnEntry::NewL(entryType, guid, CCalEntry::EMethodNone, 0); // dummy values for method and sequence number
       
   611 			CleanupStack::Pop(guid);
       
   612 			CleanupStack::PushL(entry);
       
   613 			
       
   614 		    TAgnCalendarTime recurId;
       
   615 
       
   616 		    const TInt KCount = aStream.ReadInt32L(); 
       
   617 		    for (TInt i = 0; i < KCount; ++i)
       
   618 				{
       
   619 				TCalLocalUid childId = aStream.ReadUint32L();	
       
   620 				aStream >> recurId;
       
   621 				
       
   622 				TGsChildRefData childData(childId, recurId);
       
   623 				entry->AddChildIdL(childData);
       
   624 				}
       
   625 		
       
   626 			// set correct value for method and sequence number
       
   627 			TInt32 seqNum = aStream.ReadInt32L();
       
   628 			entry->SetSequenceNumber(seqNum);
       
   629 			
       
   630 			CCalEntry::TMethod method = static_cast<CCalEntry::TMethod> (aStream.ReadInt8L());
       
   631 			entry->SetMethod(method);
       
   632 
       
   633 			aStream.ReadUint32L(); // parent ID (Null for a parent)
       
   634 			}
       
   635 			break;
       
   636 			
       
   637 		case EGsLeaf:
       
   638 			{
       
   639 			TInt32 seqNum = aStream.ReadInt32L();
       
   640 			CCalEntry::TMethod method = static_cast<CCalEntry::TMethod> (aStream.ReadInt8L());
       
   641 			TCalLocalUid parentId = aStream.ReadUint32L(); 
       
   642 			
       
   643 		    entry = CAgnEntry::NewL(entryType, NULL, method, seqNum, TAgnCalendarTime(), CalCommon::EThisOnly);
       
   644 		    CleanupStack::PushL(entry);
       
   645 		    entry->SetParentId(parentId);
       
   646 			}
       
   647 			break;
       
   648 
       
   649 		case EGsParent: // fall through
       
   650 		case ENonGsEntry:
       
   651 			// this is a non-GS entry, get the GUID from the unique ID, entry == NULL
       
   652 			break;
       
   653 		
       
   654 		default:
       
   655 			{
       
   656 			User::Leave(KErrCorrupt);
       
   657 			}
       
   658 		}
       
   659     
       
   660     // Read in entry's unique Id
       
   661     //
       
   662    	TCalLocalUid localUid;
       
   663     aStream >> localUid;
       
   664     
       
   665     // create entry now we have all the information
       
   666 	
       
   667 	if (!entry) // create non-GS entry from unique ID
       
   668 		{
       
   669     	TBuf8<32> uniqueIdBuf;
       
   670 	    uniqueIdBuf.AppendNum(localUid);
       
   671 	    HBufC8* guid = uniqueIdBuf.AllocLC();
       
   672 		entry = CAgnEntry::NewL(entryType, guid, CCalEntry::EMethodNone, 0);
       
   673 		CleanupStack::Pop(guid);
       
   674 		CleanupStack::PushL(entry);
       
   675 		}
       
   676 		
       
   677     entry->SetStatus(status);
       
   678     entry->SetLocalUid(localUid);
       
   679 
       
   680     // TReplicationData was next in 9.1/9.2, with the following data:
       
   681     //            TStatus iStatus;
       
   682     //            TBool iHasBeenDeleted;
       
   683     //            TUint iCount;
       
   684     //            TAgnCalendarTime iLastChangedDateUtc
       
   685     //
       
   686 	entry->SetReplicationStatusL(static_cast<CCalEntry::TReplicationStatus>(aStream.ReadInt8L()));
       
   687 
       
   688     TBool hasBeenDeleted = aStream.ReadUint8L();// Not used in 9.3 but checked later
       
   689     aStream.ReadUint8L();//skip iCount
       
   690     TAgnCalendarTime lastChangedDate;
       
   691 	aStream >> lastChangedDate;
       
   692 	entry->SetLastModifiedDateUtc(lastChangedDate.UtcL());
       
   693     
       
   694     // CAgnRptDef
       
   695     //
       
   696     // In 9.1/9.2, the second bit of the 'attributes' 
       
   697     // indicates presence/absence of a repeat definition
       
   698     // 
       
   699     CArrayFixFlat<TAgnCalendarTime>* exceptions = NULL;
       
   700     if (attributes & EBit2)
       
   701     	{
       
   702 		exceptions = InternalizeRptDefL(aStream, *entry);
       
   703 		}
       
   704 	
       
   705 	TInt32 alarmPreTime = InternalizeAlarmL(aStream, attributes, *entry);
       
   706 	InternalizeSummaryL(aStream, hasBeenDeleted, *entry);
       
   707 	InternalizeTypeSpecificDataL(aStream, attributes, *entry);
       
   708 	AddExceptionsL(*entry, exceptions); // must add exceptions after start date has been set
       
   709 	delete exceptions;
       
   710 	
       
   711 	// if the entry is floating, the until date must be converted to a floating TAgnCalendarTime
       
   712 	if (entry->TimeMode() == MAgnCalendarTimeMode::EFloating)
       
   713 		{
       
   714 		if (entry->RptDef() && entry->RptDef()->RRule())
       
   715 			{
       
   716 			if (AgnDateTime::IsValidAgendaTTime(entry->RptDef()->RRule()->UntilTimeL().UtcL()))
       
   717 				{
       
   718 				TAgnCalendarTime agnUntilTime;
       
   719 				agnUntilTime.SetFloatingL(entry->RptDef()->RRule()->UntilTimeL().UtcL());
       
   720 				entry->RptDef()->SetUntilTime(agnUntilTime);
       
   721 				}
       
   722 			}
       
   723 		}
       
   724 	
       
   725 	// if the entry has an alarm, calculate the offset from the pretime used in v9.1/v9.2
       
   726 	if (alarmPreTime != KMaxTInt32)
       
   727 		{
       
   728 		if (KV9192Type == EAgnTodo)
       
   729 			{
       
   730 			entry->SetAlarmOffset(CalculateAlarmOffsetL(alarmPreTime, entry->EndTime().LocalL()));
       
   731 			}
       
   732 		else
       
   733 			{
       
   734 			entry->SetAlarmOffset(CalculateAlarmOffsetL(alarmPreTime, entry->StartTime().LocalL()));
       
   735 			}
       
   736 		}
       
   737 	
       
   738 	CleanupStack::Pop(entry);
       
   739 	
       
   740 	return entry;
       
   741 	}
       
   742 
       
   743 CArrayFixFlat<TAgnCalendarTime>* CAgnCalendarConverter209::InternalizeRptDefL(RReadStream& aStream, CAgnEntry& aEntry) const
       
   744 	{
       
   745 	CAgnRptDef* rptDef = CAgnRptDef::NewL(aEntry);
       
   746 	CleanupStack::PushL(rptDef);
       
   747 
       
   748 	InternalizeRepeatRuleL(aStream, *rptDef);
       
   749 	CArrayFixFlat<TAgnCalendarTime>* exceptions = InternalizeExceptionsL(aStream);
       
   750 	CleanupStack::PushL(exceptions);
       
   751 	InternalizeSporadicDatesL(aStream, *rptDef);
       
   752 		
       
   753 	InternalizeTimeZoneL(aStream, *rptDef);	
       
   754 			
       
   755 	aStream.ReadUint8L(); // ignore show next only
       
   756 	
       
   757 	aEntry.SetRptDefL(*rptDef);
       
   758 	
       
   759 	CleanupStack::Pop(exceptions);
       
   760 	CleanupStack::PopAndDestroy(rptDef);
       
   761 	return exceptions;
       
   762 	}
       
   763 
       
   764 void CAgnCalendarConverter209::AddExceptionsL(CAgnEntry& aEntry, CArrayFixFlat<TAgnCalendarTime>* aExceptions) const
       
   765 	{
       
   766 	// must add exceptions after sporadic dates
       
   767 	if (aExceptions && aEntry.RptDef())
       
   768 		{
       
   769 		const TInt KCount = aExceptions->Count();
       
   770 		if (KCount > 0)
       
   771 			{
       
   772 			for (TInt i = 0; i < KCount; ++i)
       
   773 				{
       
   774 				aEntry.RptDef()->AddExceptionL((*aExceptions)[i]);
       
   775 				}
       
   776 			}
       
   777 		}
       
   778 	}
       
   779 
       
   780 void CAgnCalendarConverter209::InternalizeRepeatRuleL(RReadStream& aStream, CAgnRptDef& aRptDef) const
       
   781 	{
       
   782     TBool hasRepeatRule = aStream.ReadUint8L();
       
   783 
       
   784 	// TAgnRpt 
       
   785 	//
       
   786 	// This data member of CAgnRptDef is different in 9.3 
       
   787     //
       
   788 	if (hasRepeatRule)
       
   789 		{
       
   790 		TAgnRpt* rule = NULL;
       
   791 		TAgnRpt::TType rptType = static_cast<TAgnRpt::TType>(aStream.ReadUint8L());
       
   792 		
       
   793 		// Intenalize data in base class for repeat definitions
       
   794 		// (TAgnRpt)
       
   795 		//
       
   796 		TInt64 timeInt64;
       
   797 		aStream >> timeInt64; // ignore start time
       
   798 		aStream >> timeInt64;
       
   799 		TAgnCalendarTime untilTime;
       
   800 		untilTime.SetUtcL(timeInt64); // not right if the entry is floating, this must be fixed once the time mode is known
       
   801 
       
   802 		TUint16 interval;
       
   803 		aStream >> interval;
       
   804 		
       
   805 		// skip iRptNextOnly and iRptForever (not used in 9.3)
       
   806 		aStream.ReadUint8L();
       
   807 		aStream.ReadUint8L();
       
   808 		
       
   809 		// Internalize data in classes derived from TAgnRpt
       
   810 		//
       
   811 		switch(rptType)
       
   812 			{
       
   813 			case TAgnRpt::EDaily:
       
   814 				//Nothing else to internalize for rpt rule
       
   815 				rule = new (ELeave) TAgnDailyRpt(aRptDef);
       
   816 				CleanupStack::PushL(rule);
       
   817 				break;
       
   818 			case TAgnRpt::EWeekly:
       
   819 				{
       
   820 				rule = new (ELeave) TAgnWeeklyRpt(aRptDef);
       
   821 				CleanupStack::PushL(rule);
       
   822 				TAgnWeeklyRpt* weeklyRule = static_cast<TAgnWeeklyRpt*>(rule);
       
   823 				TUint8 weeklyRptDays = aStream.ReadUint8L();
       
   824 				if (weeklyRptDays & EBit1)
       
   825 					{
       
   826 					weeklyRule->SetDay(EMonday);	
       
   827 					}
       
   828 				if (weeklyRptDays & EBit2)
       
   829 					{
       
   830 					weeklyRule->SetDay(ETuesday);
       
   831 					}
       
   832 				if (weeklyRptDays & EBit3)
       
   833 					{
       
   834 					weeklyRule->SetDay(EWednesday);
       
   835 					}
       
   836 				if (weeklyRptDays & EBit4)
       
   837 					{
       
   838 					weeklyRule->SetDay(EThursday);
       
   839 					}
       
   840 				if (weeklyRptDays & EBit5)
       
   841 					{
       
   842 					weeklyRule->SetDay(EFriday);
       
   843 					}
       
   844 				if (weeklyRptDays & EBit6)
       
   845 					{
       
   846 					weeklyRule->SetDay(ESaturday);
       
   847 					}
       
   848 				if (weeklyRptDays & EBit7)
       
   849 					{
       
   850 					weeklyRule->SetDay(ESunday);
       
   851 					}
       
   852 
       
   853 				TDay firstDayOfWeek = static_cast<TDay>(aStream.ReadUint8L());
       
   854 				weeklyRule->SetFirstDayOfWeek(firstDayOfWeek);
       
   855 				}
       
   856 				break;
       
   857 			case TAgnRpt::EMonthlyByDates:
       
   858 				{
       
   859 				rule = new (ELeave) TAgnMonthlyByDatesRpt(aRptDef);
       
   860 				CleanupStack::PushL(rule);
       
   861 				TInt32 monthlyRptDates;
       
   862 				aStream >> monthlyRptDates;
       
   863 				for (TInt i = 0; i <= 30; ++i) // check 31 dates
       
   864 					{
       
   865 					TInt dateToCheck = 1 << i;
       
   866 					if (monthlyRptDates & dateToCheck)
       
   867 						{
       
   868 						static_cast<TAgnMonthlyByDatesRpt*>(rule)->SetDate(i);
       
   869 						}
       
   870 					}
       
   871 				}
       
   872 				break;
       
   873 			case TAgnRpt::EMonthlyByDays:
       
   874 				{
       
   875 				rule = new (ELeave) TAgnMonthlyByDaysRpt(aRptDef);
       
   876 				CleanupStack::PushL(rule);
       
   877 				TAgnMonthlyByDaysRpt* monthlyRule = static_cast<TAgnMonthlyByDaysRpt*>(rule);
       
   878 				
       
   879 				TInt weekInMonth = 0;
       
   880 				while (weekInMonth <= 4) // 5 weeks in month (1st, 2nd, 3rd, 4th, last)
       
   881 					{
       
   882 					TUint8 monthlyRptDays = aStream.ReadUint8L();
       
   883 					if (monthlyRptDays & EBit1)
       
   884 						{
       
   885 						monthlyRule->SetDay(EMonday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth));	
       
   886 						}
       
   887 					if (monthlyRptDays & EBit2)
       
   888 						{
       
   889 						monthlyRule->SetDay(ETuesday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth));
       
   890 						}
       
   891 					if (monthlyRptDays & EBit3)
       
   892 						{
       
   893 						monthlyRule->SetDay(EWednesday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth));
       
   894 						}
       
   895 					if (monthlyRptDays & EBit4)
       
   896 						{
       
   897 						monthlyRule->SetDay(EThursday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth));
       
   898 						}
       
   899 					if (monthlyRptDays & EBit5)
       
   900 						{
       
   901 						monthlyRule->SetDay(EFriday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth));
       
   902 						}
       
   903 					if (monthlyRptDays & EBit6)
       
   904 						{
       
   905 						monthlyRule->SetDay(ESaturday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth));
       
   906 						}
       
   907 					if (monthlyRptDays & EBit7)
       
   908 						{
       
   909 						monthlyRule->SetDay(ESunday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth));
       
   910 						}
       
   911 					++weekInMonth;
       
   912 					}
       
   913 				}
       
   914 				break;
       
   915 			case TAgnRpt::EYearlyByDay:
       
   916 				{
       
   917 				rule = new (ELeave) TAgnYearlyByDayRpt(aRptDef);
       
   918 				CleanupStack::PushL(rule);
       
   919 				TAgnRpt::TWeekInMonth weekInMonth = static_cast<TAgnRpt::TWeekInMonth>(aStream.ReadUint8L());
       
   920 				TDay day = static_cast<TDay>(aStream.ReadUint8L());
       
   921 				TDateTime untilDateTime = untilTime.LocalL().DateTime();
       
   922 				static_cast<TAgnYearlyByDayRpt*>(rule)->FindStartDayL(day, weekInMonth, untilDateTime.Month(), untilDateTime.Year());
       
   923 				}
       
   924 				break;
       
   925 			case TAgnRpt::EYearlyByDate:
       
   926 				rule = new (ELeave) TAgnYearlyByDateRpt(aRptDef);
       
   927 				CleanupStack::PushL(rule);
       
   928 				break;
       
   929 			default:
       
   930 				User::Leave(KErrCorrupt);
       
   931 			}
       
   932 		rule->SetInterval(interval);
       
   933 		
       
   934 		aRptDef.SetRRuleL(*rule);
       
   935 		aRptDef.SetUntilTime(untilTime);
       
   936 		CleanupStack::PopAndDestroy(rule);
       
   937 		}
       
   938 	}
       
   939 
       
   940 CArrayFixFlat<TAgnCalendarTime>* CAgnCalendarConverter209::InternalizeExceptionsL(RReadStream& aStream) const
       
   941 	{
       
   942 	CArrayFixFlat<TAgnCalendarTime>* exceptionArray = NULL;
       
   943 	if (aStream.ReadUint8L())
       
   944 		{
       
   945 		const TInt KExceptionArrayGranularity = 4;
       
   946 		
       
   947 		exceptionArray = new (ELeave) CArrayFixFlat<TAgnCalendarTime>(KExceptionArrayGranularity);
       
   948 		CleanupStack::PushL(exceptionArray);
       
   949 		aStream >> *exceptionArray;
       
   950 		CleanupStack::Pop(exceptionArray);
       
   951 		}
       
   952 	return exceptionArray;
       
   953 	}
       
   954 
       
   955 void CAgnCalendarConverter209::InternalizeSporadicDatesL(RReadStream& aStream, CAgnRptDef& aRptDef) const
       
   956 	{
       
   957 	const TInt KCount = aStream.ReadUint16L();
       
   958 	if (KCount > 0)
       
   959 		{
       
   960 		TAgnCalendarTime time;
       
   961 		for (TInt i = 0; i < KCount; ++i)
       
   962 			{
       
   963 			aStream >> time;
       
   964 			aRptDef.AddSporadicDateL(time);
       
   965 			}
       
   966 		}
       
   967 	}
       
   968 
       
   969 void CAgnCalendarConverter209::InternalizeTimeZoneL(RReadStream& aStream, CAgnRptDef& aRptDef) const
       
   970 	{
       
   971 	// Time Zone  
       
   972 	TBool hasTimeZone = aStream.ReadUint8L();
       
   973 	if (hasTimeZone)
       
   974 		{
       
   975 		CTzRules* tzRules = CTzRules::NewL(aStream);
       
   976 		CleanupStack::PushL(tzRules);
       
   977 		aRptDef.SetTimeZoneL(*tzRules);
       
   978 		CleanupStack::PopAndDestroy(tzRules);
       
   979 		}
       
   980 	}
       
   981 
       
   982 TInt32 CAgnCalendarConverter209::InternalizeAlarmL(RReadStream& aStream, TInt16 aAttributes, CAgnEntry& aEntry) const
       
   983 	{
       
   984 	// In 9.1/9.2, the eigth bit of the 'attributes' 
       
   985 	// indicates presence/absence of a entry symbol
       
   986 	//
       
   987 	if (aAttributes & EBit8)
       
   988 		{
       
   989 		aStream.ReadInt16L();//Skip entry symbol (not used in 9.3)
       
   990 		}
       
   991 		
       
   992 	// Alarm data
       
   993 	//
       
   994 	// In 9.1/9.2, the bits 1 (EIsCrossedOut) and 5(EHasAlarm)
       
   995 	// of 'attributes' are used to tell if alarm information
       
   996 	// has been externalized or not
       
   997 	//
       
   998 	TInt32 alarmPreTime = KMaxTInt32;
       
   999 	if ( ! (aAttributes & EBit1)) 
       
  1000 		{
       
  1001 		// Entry is not a completed todo
       
  1002 		if (aAttributes & EBit5) 
       
  1003 			{
       
  1004 			// Entry has alarm info
       
  1005 			HBufC* alarmSoundName = HBufC::NewLC(aStream, KMaxAlarmSoundNameLength);
       
  1006 			if (alarmSoundName->Length() > 0)
       
  1007 				{
       
  1008 				aEntry.SetAlarmSoundNameL(*alarmSoundName);
       
  1009 				}
       
  1010 			CleanupStack::PopAndDestroy(alarmSoundName);
       
  1011 				
       
  1012 			alarmPreTime = aStream.ReadInt32L();
       
  1013 			// alarm offset is converted as an offset later once entry time is known
       
  1014 			}
       
  1015 		}
       
  1016 	return alarmPreTime;
       
  1017 	}
       
  1018 
       
  1019 void CAgnCalendarConverter209::InternalizeSummaryL(RReadStream& aStream, TBool aHasBeenDeleted, CAgnEntry& aEntry) const
       
  1020 	{
       
  1021 	// Rich Text
       
  1022 	// In 9.1/9.2 may contain several streamIds (Styles,MarkupData,text);
       
  1023 	// It may be stored inline or offline.
       
  1024 	// In 9.3, only the text is wanted for the 'Summary'.
       
  1025 	// 
       
  1026 	if ( ! aHasBeenDeleted)
       
  1027 		{
       
  1028 		TBool isStoredInline = TBool(aStream.ReadInt8L());
       
  1029 		
       
  1030 		// Create auxiliary RichText object
       
  1031 		CParaFormatLayer* paraFormatLayer = CParaFormatLayer::NewL();
       
  1032 		CleanupStack::PushL(paraFormatLayer);
       
  1033 		
       
  1034 		CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL();
       
  1035 		CleanupStack::PushL(charFormatLayer);
       
  1036 		
       
  1037 		CRichText *auxRichText = CRichText::NewL(paraFormatLayer,charFormatLayer,CEditableText::EFlatStorage,32);
       
  1038 		CleanupStack::PushL(auxRichText);
       
  1039 		// Populate the rich text object
       
  1040 		//
       
  1041 		if (isStoredInline)
       
  1042 			{
       
  1043 			auxRichText->InternalizeStyleDataL(aStream);
       
  1044 			TBool hasMarkupData=TBool(aStream.ReadUint8L());
       
  1045 			if (hasMarkupData)
       
  1046 				{
       
  1047 				auxRichText->InternalizeMarkupDataL(aStream);
       
  1048 				}
       
  1049 			auxRichText->InternalizePlainTextL(aStream);
       
  1050 			}
       
  1051 		else
       
  1052 			{
       
  1053 			// Rich Text stored offline
       
  1054 			TStreamId richTextStreamId;
       
  1055 			aStream >> richTextStreamId;
       
  1056 			if (richTextStreamId != KNullStreamId)
       
  1057 				{
       
  1058 				RStoreReadStream richTextStream;
       
  1059 				CleanupClosePushL(richTextStream);
       
  1060 				richTextStream.OpenL(InputStreamStore(),richTextStreamId);
       
  1061 				CPersistentStore* embeddedStore = CEmbeddedStore::FromLC(richTextStream);
       
  1062 				auxRichText->RestoreL(*embeddedStore,embeddedStore->Root());
       
  1063 				CleanupStack::PopAndDestroy(embeddedStore);
       
  1064 				CleanupStack::PopAndDestroy(&richTextStream); // richTextStream.Close()
       
  1065 				}
       
  1066 			}
       
  1067 		
       
  1068 		// Get the text if there's any and leave it in the entry
       
  1069 		//
       
  1070 		if (auxRichText->DocumentLength() > 0)
       
  1071 			{
       
  1072 			HBufC* summaryBuffer = HBufC::NewLC(auxRichText->DocumentLength());
       
  1073 			TPtr summaryBufPtr(summaryBuffer->Des());
       
  1074 			auxRichText->Extract(summaryBufPtr);
       
  1075 			
       
  1076 			// Set the summary in the entry
       
  1077 			// 
       
  1078 			aEntry.SetSummary(summaryBuffer);
       
  1079 			CleanupStack::Pop(summaryBuffer);
       
  1080 			}
       
  1081 		
       
  1082 		CleanupStack::PopAndDestroy(auxRichText);
       
  1083 		CleanupStack::PopAndDestroy(charFormatLayer);
       
  1084 		CleanupStack::PopAndDestroy(paraFormatLayer);
       
  1085 		}
       
  1086 	else
       
  1087 		{
       
  1088 		// Deleted entry has no rich text. No Summary.
       
  1089 		aEntry.SetSummaryStreamId(KNullStreamId);
       
  1090 		}
       
  1091 	}
       
  1092 
       
  1093 void CAgnCalendarConverter209::InternalizeTypeSpecificDataL(RReadStream& aStream, TInt16 aAttributes, CAgnEntry& aEntry) const
       
  1094 	{
       
  1095 	//
       
  1096 	// Restore data dependent on entry type (stored with StoreSpecificsL in 9.1/2)
       
  1097 	//
       
  1098 	TAgnCalendarTime time;
       
  1099 	
       
  1100 	const CCalEntry::TType KEntryType = aEntry.Type();
       
  1101 	switch(KEntryType)
       
  1102 		{
       
  1103 		case CCalEntry::EAppt:
       
  1104 		case CCalEntry::EReminder:
       
  1105 		case CCalEntry::EEvent:
       
  1106 		case CCalEntry::EAnniv:
       
  1107 			{
       
  1108 			aStream >> time;
       
  1109 
       
  1110 			TAgnCalendarTime endTime;
       
  1111 			aStream >> endTime;;
       
  1112 			
       
  1113 			if ( ! endTime.IsSet())
       
  1114 				{
       
  1115 				aEntry.SetStartAndEndTimeL(time, time);
       
  1116 				}
       
  1117 			else
       
  1118 				{
       
  1119 				aEntry.SetStartAndEndTimeL(time, endTime);
       
  1120 				}
       
  1121 				
       
  1122 			if (KEntryType == CCalEntry::EAnniv || KEntryType == CCalEntry::EEvent)
       
  1123 				{
       
  1124 				aStream >> time; // Events and Anniversaries have a display time, not used in 9.3
       
  1125 				if (KEntryType == CCalEntry::EAnniv)
       
  1126 					{
       
  1127 					aStream.ReadInt16L(); // Skip iBaseYear
       
  1128 					aStream.ReadUint8L(); // Skip iDisplayAs
       
  1129 					aStream.ReadInt8L(); // Skip iHasBaseYear
       
  1130 					}
       
  1131 				}
       
  1132 		    break;
       
  1133 			}
       
  1134 		    
       
  1135 		case CCalEntry::ETodo:
       
  1136 			{
       
  1137 		    aStream.ReadInt32L(); // Skip iTodoListId
       
  1138 		    aStream >> time; // Was iDueDate in 9.1/2
       
  1139 		    if(aAttributes & EBit1)
       
  1140 		    	{
       
  1141 		    	// Is a crossed out (completed) Todo
       
  1142 		    	//
       
  1143 		    	TAgnCalendarTime completedDate;
       
  1144 		    	aStream >> completedDate;
       
  1145 		    	aEntry.SetCompletedDateUtcL(completedDate.UtcL());
       
  1146 		    	}
       
  1147 		    else
       
  1148 		    	{
       
  1149 		    	// This is not a completed Todo
       
  1150 		    	aEntry.SetCompletedDateUtcL(Time::NullTTime());
       
  1151 		    	}
       
  1152 		    
       
  1153 		    if (time.IsSet()) // = end time
       
  1154 		    	{
       
  1155 		    	TInt duration = aStream.ReadUint16L();
       
  1156 		    	TTimeIntervalDays intervalDays(duration);	    
       
  1157 		    	TAgnCalendarTime startTime;
       
  1158 		    	if (time.TimeMode() == MAgnCalendarTimeMode::EFloating)
       
  1159 		    		{
       
  1160 		    		startTime.SetFloatingL(time.LocalL() - intervalDays);
       
  1161 		    		}
       
  1162 		    	else
       
  1163 		    		{
       
  1164 		    		startTime.SetLocalL(time.LocalL() - intervalDays);
       
  1165 		    		}
       
  1166 				aEntry.SetStartAndEndTimeL(startTime, time);
       
  1167 		    	}
       
  1168 		    
       
  1169          	aStream.ReadUint8L();// Skip iAlarmFrom
       
  1170 		    aStream >> time; // Not used in 9.3
       
  1171          	aEntry.SetPriority(aStream.ReadUint8L()); // For Todos, use this priority; for other entry types, take priority from the extended entry
       
  1172 		    aStream.ReadUint8L(); //Skip iDisplayDueDateAs
       
  1173 			}
       
  1174 		    break;
       
  1175 		}
       
  1176 	}
       
  1177 
       
  1178 /** Algorithm to calculate the alarm offset from the 'pretime' and the 'alarm origin'.
       
  1179 This algorithm is used in v9.1 and v9.2 code. The alarm origin is the instance time corresponding to the alarm.
       
  1180 The pretime is the value saved to file, it is a combination of the minute of the day (0-1440) and the number of
       
  1181 days before the event that the alarm occurs.
       
  1182 @internalComponent */
       
  1183 TInt32 CAgnCalendarConverter209::CalculateAlarmOffsetL(TInt32 aPreTime, const TTime& aAlarmOrigin) const
       
  1184 	{
       
  1185 	// copied from TAgnAlarmPreTime::AlarmInstanceDateTime and TAgnAlarmPreTime::AlarmTime
       
  1186 	TDateTime alarmOriginDateTime = aAlarmOrigin.DateTime();
       
  1187 	TInt alarmOriginTimeOfDay = alarmOriginDateTime.Hour()*60 + alarmOriginDateTime.Minute();
       
  1188 	
       
  1189 	TUint daysWarning = (aPreTime - alarmOriginTimeOfDay) / KAgnMinutesInADay;
       
  1190 	TUint time = KAgnMinutesInADay - ((aPreTime - alarmOriginTimeOfDay) % KAgnMinutesInADay);
       
  1191 	if (time == KAgnMinutesInADay)
       
  1192 		{
       
  1193 		time = 0;
       
  1194 		if (daysWarning > 0)
       
  1195 			{
       
  1196 			daysWarning -= 1;
       
  1197 			}
       
  1198 		}
       
  1199 
       
  1200 	TTime alarmTime = aAlarmOrigin - TTimeIntervalDays(daysWarning);
       
  1201 	TDateTime alarmDateTime = alarmTime.DateTime();
       
  1202 	alarmDateTime.SetHour(time / 60);
       
  1203 	alarmDateTime.SetMinute(time % 60);
       
  1204 	TTimeIntervalMinutes offset;
       
  1205 	aAlarmOrigin.MinutesFrom(TTime(alarmDateTime), offset);
       
  1206 	return offset.Int();
       
  1207 	}
       
  1208 
       
  1209 void CAgnCalendarConverter209::InternalizeExtendedEntryL(RReadStream& aStream, CAgnEntry& aEntry)
       
  1210 /** @internalComponent */
       
  1211 	{
       
  1212     // Internalize information that in 9.1/9.2 lives in the Extended entry
       
  1213     //
       
  1214     TInt id = aStream.ReadUint32L(); //Not in 9.3, but needed later in this method
       
  1215     TInt size = aStream.ReadUint32L();
       
  1216     
       
  1217     // Skip GlobalId
       
  1218     TBuf<32> dummyBuffer;
       
  1219     if (size)
       
  1220     	{
       
  1221     	aStream.ReadL(dummyBuffer,size);
       
  1222     	}
       
  1223     
       
  1224     // Populate location
       
  1225     //
       
  1226 	size = aStream.ReadUint32L();
       
  1227 	if (size)
       
  1228 		{
       
  1229 		HBufC* location = HBufC::NewLC(size);
       
  1230 		TPtr bufPtr = location->Des();
       
  1231 		aStream.ReadL(bufPtr,size);
       
  1232 		aEntry.SetLocationL(*location);
       
  1233 		CleanupStack::PopAndDestroy();
       
  1234 		}
       
  1235     
       
  1236     // Populate attendee list
       
  1237     // 
       
  1238     size = aStream.ReadUint32L();
       
  1239 	
       
  1240 	RPointerArray<CAgnAttendee> attendees;
       
  1241 	CleanupClosePushL(attendees);
       
  1242 	
       
  1243 	for (TInt count=0; count < size; count++)
       
  1244 		{
       
  1245 		TBool organizer = EFalse;
       
  1246 		CAgnAttendee* attendee = InternalizeAttendeeL(aStream, organizer);
       
  1247 		if (organizer)
       
  1248 			{
       
  1249 			aEntry.SetOrganizerL(attendee);
       
  1250 			}
       
  1251 		else
       
  1252 			{
       
  1253 			aEntry.AddAttendeeL(attendee);
       
  1254 			}
       
  1255 		attendees.AppendL(attendee);
       
  1256 		}
       
  1257 	
       
  1258 	// populate the phoneowner/organizer fields 
       
  1259 	//
       
  1260 	size = aStream.ReadUint32L();
       
  1261 	
       
  1262 	if(size > 0 && size <= attendees.Count())
       
  1263 		{
       
  1264 		aEntry.SetPhoneOwnerL(attendees[size-1]);
       
  1265 		}
       
  1266 	
       
  1267 	size = aStream.ReadUint32L();
       
  1268 	
       
  1269 	if(size > 0 && size <= attendees.Count())
       
  1270 		{
       
  1271 		CAgnAttendee* organizer = attendees[size-1]->CloneL();
       
  1272 		CleanupStack::PushL(organizer);
       
  1273 		aEntry.SetOrganizerL(organizer);
       
  1274 		CleanupStack::Pop(organizer);
       
  1275 		}
       
  1276 	CleanupStack::PopAndDestroy(&attendees); // attendees.Close()
       
  1277 	
       
  1278 	// Populate DT stamp
       
  1279 	//
       
  1280 	TAgnCalendarTime dtStamp;
       
  1281 	aStream >> dtStamp;
       
  1282 	aEntry.SetDTStampUtcL(dtStamp.UtcL());
       
  1283 	
       
  1284 	TInt expansion = aStream.ReadUint8L(); // read number of bytes in expansion 
       
  1285 	// Only try to internalize category information if it exists
       
  1286 	if (expansion>0)
       
  1287 		{
       
  1288 		
       
  1289 		// Read in categories
       
  1290 		//
       
  1291 		size = aStream.ReadUint32L();
       
  1292 
       
  1293 		for (TInt ccount=0; ccount<size; ccount++)
       
  1294 			{
       
  1295 			CAgnCategory* category = InternalizeCategoryL(aStream);
       
  1296 			CleanupStack::PushL(category);
       
  1297 			aEntry.AddCategoryL(category);
       
  1298 			CleanupStack::Pop(category);
       
  1299 			}
       
  1300 		
       
  1301 		// Skip iBackgroundSymbolColor
       
  1302 		aStream.ReadUint8L();
       
  1303 		aStream.ReadUint8L();
       
  1304 		aStream.ReadUint8L();
       
  1305 		
       
  1306 		// If it's the new file format read in the Stream Id for the notes text
       
  1307 		const TInt KExtendedAttributesIdv1_0 = 0x110000F2; // from 9.1 / 9.2
       
  1308 		
       
  1309 		if (id == KExtendedAttributesIdv1_0) 
       
  1310 			{
       
  1311 			// Set the priority for entries that are not Todos (for Todos it's been set already)
       
  1312 			if (aEntry.Type() != CCalEntry::ETodo)
       
  1313 				{
       
  1314 				aEntry.SetPriority(aStream.ReadUint8L());
       
  1315 				}
       
  1316 			else
       
  1317 				{
       
  1318 				// Skip the priority
       
  1319 				aStream.ReadUint8L();
       
  1320 				}
       
  1321 			
       
  1322 			// 	9.1/2 "Notes" field is "Description" in 9.3
       
  1323 			TStreamId descriptionStreamId;
       
  1324 			aStream >> descriptionStreamId;
       
  1325 			
       
  1326 			if(descriptionStreamId != KNullStreamId) 
       
  1327 				{
       
  1328 				// Put the description in the aEntry
       
  1329 				//
       
  1330 				RStoreReadStream in;
       
  1331 				in.OpenLC(InputStreamStore(), descriptionStreamId);
       
  1332 				TInt textLength = in.ReadUint32L();
       
  1333 				if(textLength > 0)
       
  1334 					{
       
  1335 					HBufC* text = HBufC::NewL(in, textLength);
       
  1336 					aEntry.SetDescription(text);
       
  1337 					}
       
  1338 				CleanupStack::PopAndDestroy(); //in
       
  1339 				}
       
  1340 	
       
  1341 			// Ignore iNotesClipboardStreamId
       
  1342 			TStreamId clipboardStreamId;
       
  1343 			aStream >> clipboardStreamId;	
       
  1344 			}
       
  1345 		}
       
  1346 	}
       
  1347 
       
  1348 CAgnCategory* CAgnCalendarConverter209::InternalizeCategoryL(RReadStream& aStream) const
       
  1349 	{
       
  1350 	CCalCategory::TCalCategoryType categoryType = static_cast<CCalCategory::TCalCategoryType>(aStream.ReadUint8L());
       
  1351 	
       
  1352 	TInt size = aStream.ReadUint32L();
       
  1353 	HBufC* extendedCategoryName = HBufC::NewLC(size);
       
  1354 	TPtr bufPtr = extendedCategoryName->Des();
       
  1355 	aStream.ReadL(bufPtr,size);
       
  1356 
       
  1357 	CAgnCategory* category = NULL;
       
  1358 	if (categoryType == CCalCategory::ECalExtended || extendedCategoryName->Length() > 0)
       
  1359 		{
       
  1360 		category = CAgnCategory::NewL(*extendedCategoryName);
       
  1361 		}
       
  1362 	else
       
  1363 		{
       
  1364 		category = CAgnCategory::NewL(categoryType);
       
  1365 		}
       
  1366 	CleanupStack::PopAndDestroy(extendedCategoryName);
       
  1367 	return category;
       
  1368 	}
       
  1369 
       
  1370 CAgnAttendee* CAgnCalendarConverter209::InternalizeAttendeeL(RReadStream& aStream, TBool& aOrganizer) const
       
  1371 	{
       
  1372 	CAgnAttendee::TAgnRole agnRole = static_cast<CAgnAttendee::TAgnRole>(aStream.ReadUint8L());
       
  1373 	aStream.ReadUint8L();// Skip iStatus
       
  1374 	TBool responseRequested = aStream.ReadUint8L();
       
  1375 	aStream.ReadUint8L(); // ignore expect value
       
  1376 	CCalAttendee::TCalRole calRole = static_cast<CCalAttendee::TCalRole>(aStream.ReadUint8L());
       
  1377 	CCalAttendee::TCalStatus calStatus = static_cast<CCalAttendee::TCalStatus>(aStream.ReadUint8L());
       
  1378 		
       
  1379 	//	read in Address
       
  1380 	TInt size = aStream.ReadUint32L();
       
  1381 	HBufC* address = HBufC::NewLC(size);
       
  1382 	TPtr bufPtr = address->Des();
       
  1383 	aStream.ReadL(bufPtr,size);
       
  1384 	
       
  1385 	size = aStream.ReadUint32L();
       
  1386 	HBufC* commonName = HBufC::NewLC(size);
       
  1387 	TPtr bufPtr2 = commonName->Des();
       
  1388 	aStream.ReadL(bufPtr2,size);	
       
  1389 
       
  1390 	size = aStream.ReadUint32L();
       
  1391 	HBufC* sentBy = HBufC::NewLC(size);
       
  1392 	TPtr bufPtr3 = sentBy->Des();
       
  1393 	aStream.ReadL(bufPtr3,size);
       
  1394 
       
  1395 	CAgnAttendee* attendee = CAgnAttendee::NewL(*address, *sentBy);
       
  1396 	CleanupStack::PushL(attendee);
       
  1397 	attendee->SetCommonNameL(*commonName);
       
  1398 	
       
  1399 	attendee->SetResponseRequested(responseRequested);
       
  1400 	attendee->SetRole(agnRole);
       
  1401 	if (agnRole == CAgnAttendee::EOrganizer)
       
  1402 		{
       
  1403 		aOrganizer = ETrue;
       
  1404 		}
       
  1405 	attendee->SetCalStatus(calStatus);
       
  1406 	
       
  1407 	CleanupStack::Pop(attendee);
       
  1408 	CleanupStack::PopAndDestroy(sentBy);
       
  1409 	CleanupStack::PopAndDestroy(commonName);
       
  1410 	CleanupStack::PopAndDestroy(address);
       
  1411 
       
  1412 	return attendee;
       
  1413 	}
       
  1414 	
       
  1415 // CAgnCalendarConverter210 //
       
  1416 
       
  1417 CAgnCalendarConverter210::CAgnCalendarConverter210()
       
  1418 	{
       
  1419 	}
       
  1420 
       
  1421 CAgnCalendarConverter210* CAgnCalendarConverter210::NewL(CAgnServFile& aAgnServerFile)
       
  1422 	{
       
  1423 	CAgnCalendarConverter210* converter = new (ELeave) CAgnCalendarConverter210();
       
  1424 	CleanupStack::PushL(converter);
       
  1425 	converter->ConstructL(aAgnServerFile);
       
  1426 	CleanupStack::Pop(converter);
       
  1427 	return converter;
       
  1428 	}
       
  1429 
       
  1430 void CAgnCalendarConverter210::InternalizeExtendedEntryL(RReadStream& aStream, CAgnEntry& aEntry)
       
  1431 	{
       
  1432 	CAgnCalendarConverter209::InternalizeExtendedEntryL(aStream, aEntry);
       
  1433 	InternalizeAlarmActionL(aStream, InputStreamStore(), aEntry);
       
  1434 	}
       
  1435 
       
  1436 /** 
       
  1437 Internalize alarm action
       
  1438 @internalComponent */
       
  1439 void CAgnCalendarConverter210::InternalizeAlarmActionL(RReadStream& aStream, CStreamStore& aInputStreamStore, CAgnEntry& aEntry)
       
  1440 	{
       
  1441 	TStreamId alarmActionStreamId;
       
  1442 	aStream >> alarmActionStreamId;
       
  1443 	if ( alarmActionStreamId != KNullStreamId)
       
  1444 		{
       
  1445        	RStoreReadStream in;
       
  1446 	   	in.OpenLC(aInputStreamStore, alarmActionStreamId);
       
  1447 		CAgnContent* alarmAction = new (ELeave) CAgnContent;
       
  1448 		CleanupStack::PushL(alarmAction);
       
  1449 		in >> *alarmAction;
       
  1450 		aEntry.SetAlarmAction(alarmAction);
       
  1451 		CleanupStack::Pop(alarmAction);
       
  1452 		CleanupStack::PopAndDestroy(); //in
       
  1453   		}
       
  1454 	}
       
  1455 
       
  1456 // CAgnCalendarConverter211 //
       
  1457 CAgnCalendarConverter211* CAgnCalendarConverter211::NewL(CAgnServFile& aAgnServerFile)
       
  1458 	{
       
  1459 	CAgnCalendarConverter211* converter = new (ELeave) CAgnCalendarConverter211();
       
  1460 	CleanupStack::PushL(converter);
       
  1461 	converter->ConstructL(aAgnServerFile);
       
  1462 	CleanupStack::Pop(converter);
       
  1463 	return converter;
       
  1464 	}
       
  1465 
       
  1466 CAgnCalendarConverter211::CAgnCalendarConverter211()
       
  1467 	{
       
  1468 	}
       
  1469 
       
  1470 CAgnCalendarConverter211::~CAgnCalendarConverter211()
       
  1471 	{
       
  1472 	delete iInputTzRuleIndex;
       
  1473 	}
       
  1474 
       
  1475 void CAgnCalendarConverter211::ConstructL(CAgnServFile& aAgnServerFile)
       
  1476 	{
       
  1477 	CAgnCalendarConverter::ConstructL(aAgnServerFile);
       
  1478 	iInputTzRuleIndex = CAgnTzRuleIndex::NewL(*aAgnServerFile.Dictionary(), *aAgnServerFile.StoreL());
       
  1479 	}
       
  1480 
       
  1481 void CAgnCalendarConverter211::InternalizeTimeZoneL(RReadStream& aStream, CAgnRptDef& aRptDef) const
       
  1482 	{
       
  1483  	TBool isSystemRule = aStream.ReadUint8L();
       
  1484  	TStreamId streamId;
       
  1485  	aStream >> streamId;
       
  1486  	
       
  1487  	if(streamId != KNullStreamId)
       
  1488  		{
       
  1489  		CTzRules* tzRule = iInputTzRuleIndex->FindTzRuleByStreamIdL(streamId, isSystemRule);
       
  1490  		CleanupStack::PushL(tzRule);
       
  1491  		aRptDef.SetTimeZoneL(*tzRule);
       
  1492  		CleanupStack::PopAndDestroy(tzRule);
       
  1493  		}
       
  1494 	}
       
  1495 
       
  1496