phonebookengines/contactsmodel/cntplsql/src/cntpersistenceutility.cpp
branchRCL_3
changeset 20 f4a778e096c2
parent 0 e686773b3f54
equal deleted inserted replaced
19:5b6f26637ad3 20:f4a778e096c2
       
     1 // Copyright (c) 2007-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 /**
       
    17  @file
       
    18  @internalComponent
       
    19  @released
       
    20 */
       
    21 
       
    22 #include "cntpersistenceutility.h"
       
    23 #include "dbsqlconstants.h"
       
    24 #include "CNTSTD.H"
       
    25 #include <cntfield.h>
       
    26 #include <cntfldst.h>
       
    27 #include <s32mem.h>
       
    28 	
       
    29 /**
       
    30 Utility method used to read blob fields from contacts database, Provides a mechanism to 
       
    31 fill a contact item with informations stored in blob fields within contact database. 
       
    32 Currently we have two types of blobs within contact database: text blobs and binary blobs.
       
    33 This method will forward the call to utility methods to read from text blob and from binary
       
    34 blob as well.
       
    35 A reference to the contact item to be fill has to be provided. A template has to be provided
       
    36 if the contact item is based on a template. Template can be NULL. Also a view definition can
       
    37 be provided to filter which fields are read from blob fields.
       
    38 
       
    39 @param		aItem Contact item to be filled with information from blob fields.
       
    40 @param		aView View definition specifying what item fields should be read from blob fields
       
    41 @param		aTemplate Contact item representing a template based on which aItem should be read. Can be NULL
       
    42 @param		aDatabase RSqlDatabase reference.
       
    43 @leave		KErrNotFound if the specified contact item does not exist any more in contact database
       
    44 */	
       
    45 void TCntPersistenceUtility::ReadBlobL(CContactItem& aItem, const CContactItemViewDef& aView, const CContactItem* aTemplate, RSqlDatabase& aDatabase)
       
    46 	{
       
    47 	ReadTextBlobL(aItem, aView, aTemplate, aDatabase);
       
    48 	ReadBinaryBlobL(aItem, aView, aTemplate, aDatabase);
       
    49 	}
       
    50 
       
    51 /**
       
    52 Utility method used to read text blob fields from contacts database. Provides a mechanism to
       
    53 fill a contact item with informations stored in text blobs within contact database.
       
    54 A reference to the contact item to be fill has to be provided. A template has to be provided
       
    55 if the contact item is based on a template. Template can be NULL. Also a view definition can
       
    56 be provided to filter which fields are read from blob fields.
       
    57 
       
    58 @param 		aTextHeader reference to a read stream from which header values will be read
       
    59 @param 		aTextValues reference to a descriptor from which text values will be read
       
    60 @param		aItem Contact item to be filled with information from text blob field.
       
    61 @param		aView View definition specifying what item fields should be read from text blob field
       
    62 @param		aTemplate Contact item representing a template based on which aItem should be read. Can be NULL
       
    63 @leave		KErrNotFound if the specified contact item does not exist any more in contact database
       
    64 */	
       
    65 void TCntPersistenceUtility::ReadTextBlobL(CEmbeddedStore& aTextHeaderStore, TPtrC& aTextValues, CContactItem& aItem, const CContactItemViewDef& aView, const CContactItem* aTemplate)
       
    66 	{
       
    67 	HBufC* textFieldsBuf = aTextValues.AllocLC();
       
    68 	
       
    69 	if (aTemplate) 
       
    70 		{
       
    71 		// If a system template is provided, we create a new CContactItemFieldSet object
       
    72 		// and restore it based on provided template (CContactItemField objects composing
       
    73 		// template). CContactItem object will be set with the newly created CContactItemFieldSet.
       
    74 		CContactItemFieldSet* original = CContactItemFieldSet::NewLC();
       
    75 		RestoreTextL(*original, aTextHeaderStore, aTextHeaderStore.Root(), textFieldsBuf, aView, aTemplate);
       
    76 		
       
    77 		for(TInt loop = 0;loop < original->Count();loop++)
       
    78 			{
       
    79 			CContactItemField* additionalField = CContactItemField::NewLC((*original)[loop]);
       
    80 			aItem.CardFields().AddL(*additionalField);
       
    81 			CleanupStack::Pop(additionalField);
       
    82 			}
       
    83 		CleanupStack::PopAndDestroy(original);
       
    84 		}
       
    85 	else
       
    86 		{
       
    87 		// If there is no template provided, we will fill the CContactItemField set provided
       
    88 		// in the curent CContactItem object
       
    89 		RestoreTextL(aItem.CardFields(), aTextHeaderStore, aTextHeaderStore.Root(), textFieldsBuf, aView, NULL);
       
    90 		}
       
    91 	
       
    92 	CleanupStack::PopAndDestroy(textFieldsBuf); 
       
    93 	}
       
    94 
       
    95 
       
    96 /**
       
    97 Utility method used to read text blob fields from contacts database. Provides a mechanism to
       
    98 fill a contact item with informations stored in text blobs within contact database.
       
    99 A reference to the contact item to be fill has to be provided. A template has to be provided
       
   100 if the contact item is based on a template. Template can be NULL. Also a view definition can
       
   101 be provided to filter which fields are read from blob fields.
       
   102 
       
   103 @param		aItem Contact item to be filled with information from text blob field.
       
   104 @param		aView View definition specifying what item fields should be read from text blob field
       
   105 @param		aTemplate Contact item representing a template based on which aItem should be read. Can be NULL
       
   106 @param		aDatabase RSqlDatabase reference.
       
   107 @leave		KErrNotFound if the specified contact item does not exist any more in contact database
       
   108 */	
       
   109 void TCntPersistenceUtility::ReadTextBlobL(CContactItem& aItem, const CContactItemViewDef& aView, const CContactItem* aTemplate, RSqlDatabase& aDatabase)
       
   110 	{
       
   111 	HBufC* selectString = HBufC::NewLC(KSelectTwoFields().Length() + KContactTextFieldHeader().Length() + KContactTextFields().Length() + KSqlContactTableName().Length() + KContactId().Length());
       
   112 	TPtr ptrSelectString = selectString->Des();
       
   113 	ptrSelectString.Format(KSelectTwoFields, &KContactTextFieldHeader, &KContactTextFields, &KSqlContactTableName, &KContactId, aItem.Id());
       
   114 	
       
   115 	RSqlStatement selectStmt;
       
   116 	CleanupClosePushL(selectStmt);
       
   117 	User::LeaveIfError(selectStmt.Prepare(aDatabase, ptrSelectString));
       
   118 
       
   119 	TInt err = selectStmt.Next();
       
   120 	if(err != KSqlAtRow)
       
   121 		{
       
   122 		if(err == KSqlAtEnd) 
       
   123 			{
       
   124 			User::Leave(KErrNotFound);	
       
   125 			}
       
   126 		else
       
   127 			{
       
   128 			User::Leave(err);	
       
   129 			}	
       
   130 		}
       
   131 	
       
   132 	TPtrC8 textHeader;
       
   133 	selectStmt.ColumnBinary(User::LeaveIfError(selectStmt.ColumnIndex(KContactTextFieldHeader)), textHeader);
       
   134 	RDesReadStream textHeaderStream(textHeader);
       
   135 	CleanupClosePushL(textHeaderStream);
       
   136 
       
   137 	CEmbeddedStore* textHeaderStore = CEmbeddedStore::FromLC(textHeaderStream);
       
   138 		
       
   139 	TPtrC textFieldPtrC = selectStmt.ColumnTextL(User::LeaveIfError(selectStmt.ColumnIndex(KContactTextFields)));
       
   140 	
       
   141 	ReadTextBlobL(*textHeaderStore, textFieldPtrC, aItem, aView, aTemplate);
       
   142 
       
   143 	CleanupStack::PopAndDestroy(4, selectString); // textHeaderStore, textHeaderStream, selectStmt, selectString 	
       
   144 	}
       
   145 	
       
   146 /**
       
   147 Utility method used to read binary blob fields from contacts database. Provides a mechanism to
       
   148 fill a contact item with informations stored in binary blobs within contact database.
       
   149 A reference to the contact item to be fill has to be provided. A template has to be provided
       
   150 if the contact item is based on a template. Template can be NULL. Also a view definition can
       
   151 be provided to filter which fields are read from blob fields.
       
   152 
       
   153 @param		aBinaryHeader reference to a read stream from which header will be read
       
   154 @param		aBinaryValues reference to a read stream from which binary values will be read
       
   155 @param		aItem Contact item to be filled with information from binary blob field.
       
   156 @param		aView View definition specifying what item fields should be read from binary blob field
       
   157 @param		aTemplate Contact item representing a template based on which aItem should be read. Can be NULL
       
   158 @leave		KErrNotFound if the specified contact item does not exist any more in contact database
       
   159 */		
       
   160 void TCntPersistenceUtility::ReadBinaryBlobL(CEmbeddedStore& aBinaryHeaderStore, CEmbeddedStore& aBinaryBlobStore, CContactItem& aItem, const CContactItemViewDef& aView, const CContactItem* aTemplate)
       
   161 	{
       
   162 	if (aTemplate)
       
   163 		{
       
   164 		// If a system template is provided, we create a new CContactItemFieldSet object
       
   165 		// and restore it based on provided template (CContactItemField objects composing
       
   166 		// template).CContactItem object will be set with the newly created CContactItemFieldSet.		
       
   167 		CContactItemFieldSet* original = CContactItemFieldSet::NewLC();
       
   168 		RestoreBinaryL(*original, aBinaryHeaderStore, aBinaryHeaderStore.Root(), &aBinaryBlobStore, aView, aTemplate);
       
   169 		
       
   170 		for(TInt loop=0;loop < original->Count();loop++)
       
   171 			{
       
   172 			CContactItemField* additionalField = CContactItemField::NewLC((*original)[loop]);
       
   173 			aItem.CardFields().AddL(*additionalField);
       
   174 			CleanupStack::Pop(additionalField);
       
   175 			}
       
   176 		CleanupStack::PopAndDestroy(original);
       
   177 		}
       
   178 	else
       
   179 		{
       
   180 		// If there is no template provided, we will fill the CContactItemField set provided
       
   181 		// in the curent CContactItem object		
       
   182 		RestoreBinaryL(aItem.CardFields(), aBinaryHeaderStore, aBinaryHeaderStore.Root(), &aBinaryBlobStore, aView, NULL);
       
   183 		}
       
   184 	}
       
   185 	
       
   186 /**
       
   187 Utility method used to read binary blob fields from contacts database. Provides a mechanism to
       
   188 fill a contact item with informations stored in binary blobs within contact database.
       
   189 A reference to the contact item to be fill has to be provided. A template has to be provided
       
   190 if the contact item is based on a template. Template can be NULL. Also a view definition can
       
   191 be provided to filter which fields are read from blob fields.
       
   192 
       
   193 @param		aItem Contact item to be filled with information from binary blob field.
       
   194 @param		aView View definition specifying what item fields should be read from binary blob field
       
   195 @param		aTemplate Contact item representing a template based on which aItem should be read. Can be NULL
       
   196 @param		aDatabase RSqlDatabase reference.
       
   197 @leave		KErrNotFound if the specified contact item does not exist any more in contact database
       
   198 */	
       
   199 void TCntPersistenceUtility::ReadBinaryBlobL(CContactItem& aItem, const CContactItemViewDef& aView, const CContactItem* aTemplate, RSqlDatabase& aDatabase)
       
   200 	{
       
   201 	HBufC* selectString = HBufC::NewLC(KSelectTwoFields().Length() + KContactBinaryFieldHeader().Length() + KContactBinaryFields().Length() + KSqlContactTableName().Length() + KContactId().Length());
       
   202 	TPtr ptrSelectString = selectString->Des();
       
   203 	ptrSelectString.Format(KSelectTwoFields, &KContactBinaryFieldHeader, &KContactBinaryFields, &KSqlContactTableName, &KContactId, aItem.Id());
       
   204 	
       
   205 	RSqlStatement selectStmt;
       
   206 	CleanupClosePushL(selectStmt);
       
   207 	User::LeaveIfError(selectStmt.Prepare(aDatabase, ptrSelectString));
       
   208 
       
   209 	TInt err = selectStmt.Next();
       
   210 	if(err != KSqlAtRow)
       
   211 		{
       
   212 		if(err == KSqlAtEnd)
       
   213 			{
       
   214 			User::Leave(KErrNotFound);	
       
   215 			}
       
   216 		else
       
   217 			{
       
   218 			User::Leave(err);	
       
   219 			}	
       
   220 		}
       
   221 	
       
   222 	TPtrC8 binaryHeader;
       
   223 	selectStmt.ColumnBinary(User::LeaveIfError(selectStmt.ColumnIndex(KContactBinaryFieldHeader)), binaryHeader);
       
   224 	RDesReadStream binaryHeaderStream(binaryHeader);
       
   225 	CleanupClosePushL(binaryHeaderStream);
       
   226 	CEmbeddedStore* binaryHeaderStore = CEmbeddedStore::FromLC(binaryHeaderStream);
       
   227 	
       
   228 	TPtrC8 binaryFields;
       
   229 	selectStmt.ColumnBinary(User::LeaveIfError(selectStmt.ColumnIndex(KContactBinaryFields)), binaryFields);
       
   230 	RDesReadStream binaryFieldsStream(binaryFields);
       
   231 	CleanupClosePushL(binaryFieldsStream);
       
   232 	CEmbeddedStore* binaryBlobStore = CEmbeddedStore::FromLC(binaryFieldsStream);
       
   233 
       
   234 	ReadBinaryBlobL(*binaryHeaderStore, *binaryBlobStore, aItem, aView, aTemplate);	
       
   235 
       
   236 	CleanupStack::PopAndDestroy(6, selectString); //binaryHeaderStore, binaryHeaderStrean, binaryBlobStore, binaryBlobStream, selectStmt, selectString
       
   237 	}
       
   238 	
       
   239 	
       
   240 /**
       
   241 Utility method used to read text fields from blob and fill item field set,Provides a mechanism to restore a 
       
   242 contact item field set from text blob field within contact database.
       
   243 Blob informations are stored based on contact item field. At restore, a reference to a contact item field set
       
   244 is provided. For every contact item field in the item field set, a text restore is made.
       
   245 
       
   246 @param		aFieldSet Reference to CContactItemFieldSet. Item field set that has to be filled with informations from blob
       
   247 @param		aHeaderStore Stream store containing the header informations
       
   248 @param		aId Root id for the header stream store
       
   249 @param		aValuesStore Read stream used to read text fields from text blob
       
   250 @param		aViewDef View definition indicating which fields have to be read from blob
       
   251 @param		aTemplate Template indicating if current field set should be filled based on a template
       
   252 */	
       
   253 void TCntPersistenceUtility::RestoreTextL(CContactItemFieldSet& aFieldSet, CStreamStore& aHeaderStore, TStreamId aId, HBufC* textStream, const CContactItemViewDef& aViewDef, const CContactItem* aTemplate)
       
   254 	{
       
   255 	const TBool KIncludeFields = ( aViewDef.Use() == CContactItemViewDef::EIncludeFields );
       
   256 	
       
   257 	if (KIncludeFields && aViewDef.Count() == 0)
       
   258 		{
       
   259 		// If view definition does not contain any field we don't do anything (don't read from 
       
   260 		// blob). We simply return from method without doing anything.
       
   261 		// This is not an error condition
       
   262 		return;	
       
   263 		}
       
   264 		
       
   265 	RStoreReadStream stream;
       
   266 	stream.OpenLC(aHeaderStore,aId);
       
   267 	
       
   268 	TCardinality fieldCount;
       
   269 	stream>>fieldCount;
       
   270 	
       
   271 	TInt textFieldIndex=0;
       
   272 
       
   273 	for (TInt ii = 0; ii < fieldCount; ++ii)
       
   274 		{
       
   275 		// Restore text for every CContactItemField in provided CContactItemFieldSet.
       
   276 		CContactItemField* field = CContactItemField::NewLC();
       
   277 		
       
   278 		if(aTemplate)
       
   279 		    {
       
   280     		field->RestoreFieldTypesL(stream, &(aTemplate->CardFields()));
       
   281 		    }
       
   282 		else
       
   283 		    {
       
   284     		field->RestoreFieldTypesL(stream, NULL);
       
   285 		    }    
       
   286 		    
       
   287 		ASSERT(field->StorageType() == KStorageTypeText);
       
   288 
       
   289 		TBool fieldDefined = ETrue;
       
   290 		if(!aViewDef.MatchesAll())
       
   291 			{
       
   292 			fieldDefined = (aViewDef.Find(field->ContentType()) != KErrNotFound);
       
   293 			}
       
   294 
       
   295 		if ((!((fieldDefined && KIncludeFields) || (!fieldDefined && !KIncludeFields))) || 
       
   296 			(field->IsHidden() && aViewDef.Mode() == CContactItemViewDef::EMaskHiddenFields))
       
   297 			{
       
   298     		CleanupStack::PopAndDestroy(field); 	
       
   299 			}
       
   300 		else
       
   301 		    {
       
   302     		field->RestoreTextL(textStream, textFieldIndex);
       
   303 			aFieldSet.AddL(*field);
       
   304     		CleanupStack::Pop(field); 	
       
   305 		    }	
       
   306 		    
       
   307         ++textFieldIndex;
       
   308 		}
       
   309 	CleanupStack::PopAndDestroy(&stream);	
       
   310 	}
       
   311 
       
   312 	
       
   313 /**
       
   314 Utility method used to read binary fields from blob and fill item field set,Provides a mechanism to restore a 
       
   315 contact item field set from binary blob field within contact database.
       
   316 Blob informations are stored based on contact item field. At restore, a reference to a contact item field set
       
   317 is provided. For every contact item field in the item field set, a text restore is made.
       
   318 
       
   319 @param		aFieldSet Reference to CContactItemFieldSet. Item field set that has to be filled with informations from blob
       
   320 @param		aHeaderStore Stream store containing the header informations
       
   321 @param		aId Root id for the header stream store
       
   322 @param		aValuesStore Read stream used to read text fields from binary blob
       
   323 @param		aViewDef View definition indicating which fields have to be read from blob
       
   324 @param		aTemplate Template indicating if current field set should be filled based on a template			
       
   325 */	
       
   326 void TCntPersistenceUtility::RestoreBinaryL(CContactItemFieldSet& aFieldSet, CStreamStore& aHeaderStore, TStreamId aId, CStreamStore* aBlobStore, const CContactItemViewDef& aViewDef, const CContactItem* aTemplate)
       
   327 	{
       
   328 	const TBool KIncludeFields = aViewDef.Use() == CContactItemViewDef::EIncludeFields;
       
   329 	
       
   330 	if (KIncludeFields && aViewDef.Count() == 0)
       
   331 		{
       
   332 		// If view definition does not contain any field we don't do anything (don't read from 
       
   333 		// blob). We simply return from method without doing anything.
       
   334 		// This is not an error condition		
       
   335 		return;	
       
   336 		}
       
   337 		
       
   338 	RStoreReadStream stream;
       
   339 	stream.OpenLC(aHeaderStore,aId);
       
   340 	TCardinality fieldCount;
       
   341 	stream>>fieldCount;
       
   342 	TStreamId nestedId;
       
   343 	
       
   344 	for (TInt ii = 0; ii < fieldCount; ++ii)
       
   345 		{
       
   346 		// Restore binary value for every CContactItemField in provided CContactItemFieldSet.
       
   347 		CContactItemField* field = CContactItemField::NewLC();
       
   348 		if(aTemplate)
       
   349 			{
       
   350 			nestedId = field->RestoreFieldTypesL(stream, &(aTemplate->CardFields()));
       
   351 			}
       
   352 		else
       
   353 			{
       
   354 			nestedId = field->RestoreFieldTypesL(stream, NULL);	
       
   355 			}
       
   356 			
       
   357 		ASSERT(field->StorageType() != KStorageTypeText);
       
   358 		
       
   359 		TBool fieldDefined = ETrue;
       
   360 		if(!aViewDef.MatchesAll())
       
   361 			{
       
   362 			fieldDefined = (aViewDef.Find(field->ContentType()) != KErrNotFound);
       
   363 			}
       
   364 
       
   365 		if ((!((fieldDefined && KIncludeFields) || (!fieldDefined && !KIncludeFields))) || 
       
   366 			(field->IsHidden() && aViewDef.Mode() == CContactItemViewDef::EMaskHiddenFields))
       
   367 			{
       
   368        		CleanupStack::PopAndDestroy(field);
       
   369 			}
       
   370         else
       
   371             {
       
   372     		RStoreReadStream readStream;
       
   373         	readStream.OpenLC(*aBlobStore, nestedId);
       
   374     		field->Storage()->RestoreL(*aBlobStore, readStream);
       
   375     		CleanupStack::PopAndDestroy(&readStream);
       
   376     		aFieldSet.AddL(*field);
       
   377     		CleanupStack::Pop(field); 
       
   378             }			
       
   379 		}
       
   380 		
       
   381 	CleanupStack::PopAndDestroy(&stream); 
       
   382 	}
       
   383 	
       
   384 /**
       
   385 Utility method used to write text and binary blob fields into write streams. The write
       
   386 streams will be used to persist the blob informations in contact database.
       
   387 Provides a mechanism to get information from a contact item and store them in the
       
   388 right blob fields within contact database. Template can be NULL. 
       
   389 
       
   390 @param		aTextHeader reference to a write stream in which text header will be written
       
   391 @param		aTextValues reference to a write stream in which text values will be written.
       
   392 			From the caller point of view this reference should be a reference to a RSqlParamWriteStream instance
       
   393 @param		aBinaryHeader reference to a write stream in which binary header will be written
       
   394 @param		aBinaryValues reference to a write stream in which binary values will be written.
       
   395 @param		aItem Contact item to be filled with information from text blob field.
       
   396 @param      aSysTemplate System template item.
       
   397 */		
       
   398 void TCntPersistenceUtility::WriteBlobL(CEmbeddedStore& aTextEmbeddedStore, RWriteStream& aTextValues, CEmbeddedStore& aBinaryEmbeddedStore, CEmbeddedStore& aBinaryEmbeddedBlobStore, const CContactItem& aItem, const CContactTemplate* aSysTemplate)
       
   399 	{
       
   400 	CContactItemFieldSet& fieldSet = aItem.CardFields();
       
   401 	CContactItemFieldSet* textFieldSet = CContactItemFieldSet::NewLC();
       
   402 	CContactItemFieldSet* binaryFieldSet = CContactItemFieldSet::NewLC();
       
   403 	
       
   404 	for(TInt i = 0; i < fieldSet.Count(); ++i)
       
   405 		{
       
   406 		CContactItemField* item	= CContactItemField::NewL((aItem.CardFields())[i]);
       
   407 		CleanupStack::PushL(item);
       
   408 		if(item->StorageType() == KStorageTypeText)
       
   409 			{
       
   410 			textFieldSet->AddL(*item);	
       
   411 			}
       
   412 		else
       
   413 			{
       
   414 			binaryFieldSet->AddL(*item);	
       
   415 			}	
       
   416 		CleanupStack::Pop(item);	
       
   417 		}
       
   418 	
       
   419 	TStreamId rootId = textFieldSet->StoreL(aTextEmbeddedStore, aSysTemplate, aTextValues, aBinaryEmbeddedBlobStore, NULL);// *textEmbeddedBlobStore); 
       
   420 	aTextEmbeddedStore.SetRootL(rootId);
       
   421 	aTextEmbeddedStore.CommitL();
       
   422 
       
   423 	rootId = binaryFieldSet->StoreL(aBinaryEmbeddedStore, aSysTemplate, aTextValues, aBinaryEmbeddedBlobStore, NULL); 
       
   424 	aBinaryEmbeddedStore.SetRootL(rootId);
       
   425 	aBinaryEmbeddedStore.CommitL();
       
   426 	aBinaryEmbeddedBlobStore.CommitL();
       
   427 		
       
   428 	CleanupStack::PopAndDestroy(2, textFieldSet);  //binaryFieldSet, textFieldSet
       
   429 	}
       
   430 
       
   431 	
       
   432 /**
       
   433 Utility class to read text blob from given header stream and text buffer, and
       
   434 return an array of contact item fields defined in aTextDef.
       
   435 
       
   436 The method loops through the fields of the given text definition and adds (text)
       
   437 fields from text buffer which match the text definition field types.
       
   438 
       
   439 @param aHeaderStream the read stream contains text header blob data 
       
   440 @param aTextBuffer  text buffer storing text fields.
       
   441 @param aTextDef The text defintion containing the fields IDs required in the
       
   442 				view contact.
       
   443 @param aSearchFastAccessFields Return value indicating that additional fields can
       
   444 							   be found in the Fast Access fields.
       
   445 
       
   446 @return An array of contact item fields.
       
   447 */	
       
   448 void TCntPersistenceUtility::ReadTextBlobL(RReadStream& aHeaderStream, const HBufC* aTextBuffer, const CContactTextDef& aTextDef, const CContactTemplate& aSystemTemplate, RPointerArray<CContactItemField>& aFields, TBool& aSearchFastAccessFields)
       
   449 	{
       
   450 	TInt max = aTextDef.Count();
       
   451 	for(TInt i=0; i<max; ++i)
       
   452 		{
       
   453 		aFields.AppendL(NULL);
       
   454 		}	
       
   455 	
       
   456 	// Extract the number of fields from the header stream.
       
   457 	TCardinality headerFieldCount;
       
   458 	aHeaderStream>>headerFieldCount;
       
   459 	
       
   460 	TInt textFieldIndex = 0;
       
   461 	const TInt KMaxTextDefFlds = aTextDef.Count();
       
   462 	
       
   463 	CContactItemField* itemField = CContactItemField::NewLC();
       
   464 	for(TInt hdrFldIndex = 0; hdrFldIndex < headerFieldCount; ++hdrFldIndex)
       
   465 		{
       
   466 		// Internalization in RestoreFieldTypesL() moves headerStream on to
       
   467 		// point to the next element.  RestoreFieldTypesL() knows how to format
       
   468 		// a header element.
       
   469 		itemField->RestoreFieldTypesL(aHeaderStream, &aSystemTemplate.CardFields());
       
   470 	
       
   471 		// Loop through all the text definition fields.
       
   472 		for(TInt defIndex = 0; defIndex < KMaxTextDefFlds; ++defIndex)
       
   473 			{
       
   474 			// Check if text definition field and current header field types
       
   475 			// match.
       
   476 			if((itemField->ContentType().ContainsFieldType(aTextDef.At(defIndex).iFieldType) 
       
   477 				|| aTextDef.At(defIndex).iFieldType == KUidContactFieldMatchAll) 
       
   478 				&& itemField->StorageType() == KStorageTypeText)
       
   479 				{
       
   480 				// They do match but take care of duplicates.
       
   481 				if(aFields[defIndex] == NULL)
       
   482 					{
       
   483 					itemField->ResetStore();
       
   484 					// Restore field text from the searchable buffer.
       
   485 					itemField->RestoreTextL(const_cast<HBufC*>(aTextBuffer), textFieldIndex);
       
   486 					// Although there's an entry there may be more tables to
       
   487 					// read.
       
   488 					if(itemField->TextStorage()->Text().Length() == KNullBlobTextField().Length()
       
   489 						&& itemField->TextStorage()->Text().Compare(KNullBlobTextField) == 0)
       
   490 						{
       
   491 						aSearchFastAccessFields = ETrue;
       
   492 						}
       
   493 						
       
   494 					// Assign the array in correct sequence then clone a new one
       
   495 					// to continue the search in case there's more than one of
       
   496 					// this field type.			
       
   497 					aFields[defIndex] = CContactItemField::NewL(*itemField);
       
   498 					}
       
   499 				}
       
   500 			}
       
   501 			
       
   502 		if(itemField->StorageType() == KStorageTypeText)
       
   503 			{
       
   504 			++textFieldIndex;
       
   505 			}
       
   506 			
       
   507 		// Always one left over.
       
   508 		itemField->Reset();
       
   509 		}
       
   510 		CleanupStack::PopAndDestroy(itemField);
       
   511 	}
       
   512 
       
   513 	
       
   514 /**
       
   515 Reads the first text field from text fields blob based on aFieldType.  
       
   516 
       
   517 1. If aFieldType is KUidContactFieldMatchAll: 
       
   518 If the first text field found in the text fields blob is an Email field, 
       
   519 then the email address is returned in aText and found exit with ETrue returned, 
       
   520 If an email address is not returned, the first text field found in the text 
       
   521 field blob is returned, however it is considered as the best effort text, so 
       
   522 the calling function will return EFalse indicate the caller to found suitable
       
   523 text in Fast Access fields.
       
   524 
       
   525 2. If aFieldType is other than KUidContactFieldMatchAll: 
       
   526 Find the first text field matching aFieldType from given text fields buffer and 
       
   527 returned the field content in aText with ETrue returned, returning EFalse if it 
       
   528 can't find matched field.
       
   529 
       
   530 @param aHeaderStream The read stream contains text field header
       
   531 @param aTextFieldsBuf The text fields blob buffer.
       
   532 @param aSystemTemplate Reference to system template class.
       
   533 @param aFieldType Field type to match the field
       
   534 @param aText Text found in text fields buffer based on a FieldType. 
       
   535 */
       
   536 TBool TCntPersistenceUtility::FindTxtFieldInTextBlobL(RReadStream& aHeaderStream, HBufC* aTextFieldsBuf, const CContactTemplate& aSystemTemplate, const TFieldType& aFieldType, TDes& aText)
       
   537 	{
       
   538 	// Extract the number of fields from the header stream.
       
   539 	TCardinality headerFieldCount;
       
   540 	aHeaderStream>>headerFieldCount;
       
   541 	
       
   542 	TInt txtFldIndex = 0;
       
   543 	CContactItemField* itemField = NULL;
       
   544 	// Assign to a TInt variable to avoid using the overloaded int operator on
       
   545 	// each iteration - improves performance.
       
   546 	TInt max = headerFieldCount;
       
   547 	
       
   548 	// Loop through the header fields and try to retrieve the text from the
       
   549 	// searchable text buffer.
       
   550 	for(TInt hdrFldIndex = 0; hdrFldIndex < max; ++hdrFldIndex)
       
   551 		{
       
   552 		itemField = CContactItemField::NewLC();
       
   553 
       
   554 		// Using both header-fields and template-fields, setup the field to hold
       
   555 		// the correct type UIDs.
       
   556 		itemField->RestoreFieldTypesL(aHeaderStream, &aSystemTemplate.CardFields());
       
   557 
       
   558 		// Only restore text fields - ignore all other fields.
       
   559 		if(itemField->StorageType() == KStorageTypeText)
       
   560 			{
       
   561 			if(aFieldType == KUidContactFieldMatchAll)
       
   562 				{
       
   563 				// Restore the field text from the searchable text buffer.
       
   564 				itemField->RestoreTextL(aTextFieldsBuf, txtFldIndex);
       
   565 				
       
   566 				if(itemField->ContentType().ContainsFieldType(KUidContactFieldEMail))
       
   567 					{
       
   568 					if(CopyMinFieldText(itemField->TextStorage()->Text(), aText))
       
   569 						{
       
   570 						CleanupStack::PopAndDestroy(itemField); 
       
   571 						return ETrue;
       
   572 						}
       
   573 					}
       
   574 				else if(aText.Length() == 0 && itemField->TextStorage()->Text().Length() > 0)
       
   575 					{
       
   576 					// If there is text in the field then make a copy of the first
       
   577 					// KTextFieldMinimalLength characters.
       
   578 					CopyMinFieldText(itemField->TextStorage()->Text(), aText);
       
   579 					} //else if
       
   580 				} 
       
   581 			else if(itemField->ContentType().ContainsFieldType(aFieldType))
       
   582 				{
       
   583 				// Restore the field text from the searchable text buffer.
       
   584 				itemField->RestoreTextL(aTextFieldsBuf, txtFldIndex);
       
   585 				itemField->GetFieldText(aText);
       
   586 				//CopyMinFieldText(itemField->TextStorage()->Text(), aText);	
       
   587 				CleanupStack::PopAndDestroy(itemField); 
       
   588 				return ETrue;
       
   589 				} //else if
       
   590 				
       
   591 			++txtFldIndex;
       
   592 			} //if
       
   593 		CleanupStack::PopAndDestroy(itemField);
       
   594 		} // for
       
   595 	return EFalse;
       
   596 	}
       
   597 	
       
   598 
       
   599 /**
       
   600 Check if the field type is a identity field type.
       
   601 
       
   602 @param aFieldType The specific field requested.
       
   603 
       
   604 @return ETrue if the type is a identity field type.
       
   605 */
       
   606 TBool TCntPersistenceUtility::IsFastAccessField(TFieldType aFieldType)	
       
   607 	{
       
   608 	if(  aFieldType == KUidContactFieldGivenName 
       
   609 	   ||aFieldType == KUidContactFieldFamilyName
       
   610 	   ||aFieldType == KUidContactFieldCompanyName
       
   611 	   ||aFieldType == KUidContactFieldGivenNamePronunciation
       
   612 	   ||aFieldType == KUidContactFieldFamilyNamePronunciation
       
   613 	   ||aFieldType == KUidContactFieldCompanyNamePronunciation )
       
   614 	    {
       
   615 	    return ETrue;
       
   616 	    }
       
   617 	return EFalse;    
       
   618 	}		
       
   619 
       
   620 
       
   621 /**
       
   622 Copy a maximum of KTextFieldMinimalLength characters from aSrc to aDest.
       
   623 
       
   624 @param aSrc Source text buffer.
       
   625 @param aDest Destination text buffer.
       
   626 
       
   627 @return ETrue if copy was successfull, EFalse otherwise.
       
   628 */
       
   629 TBool TCntPersistenceUtility::CopyMinFieldText(TPtrC aSrc,TDes& aDest)
       
   630 	{
       
   631 	TBool ret(EFalse);
       
   632 	if(aSrc.Length() > 0)
       
   633 		{
       
   634 		TInt  length = aSrc.Length();
       
   635 		if (length>KTextFieldMinimalLength)
       
   636 			{
       
   637 			length=KTextFieldMinimalLength;
       
   638 			}	
       
   639 		aDest.Copy(aSrc.Left(length));
       
   640 		ret = ETrue;
       
   641 		}
       
   642 	return ret;
       
   643 	}
       
   644 
       
   645 
       
   646 /**
       
   647 Get the contact hint value from type flags.
       
   648 
       
   649 @param aTypeFlags the type flags get from contact table.
       
   650 
       
   651 @return the contact hint value.
       
   652 */
       
   653 TInt TCntPersistenceUtility::TypeFlagsToHint(TInt aTypeFlags)
       
   654 	{
       
   655 	return aTypeFlags & EContactHintFlags_Mask;
       
   656 	}	
       
   657 
       
   658 	
       
   659 /**
       
   660 Get Contact Type Uid from type flags.
       
   661 
       
   662 @param aTypeFlags the type flags get from contact table.
       
   663 
       
   664 @return the contact type UID.
       
   665 */
       
   666 TUid TCntPersistenceUtility::TypeFlagsToContactTypeUid(TInt aTypeFlags)
       
   667 	{
       
   668 	TInt contactTypeFlags = aTypeFlags >> EContactType_Shift;
       
   669 	TUid typeUid;
       
   670 	switch(contactTypeFlags)
       
   671 		{
       
   672 		case EContactTypeFlags_ContactCard:
       
   673 			typeUid = KUidContactCard;
       
   674 			break;
       
   675 		case EContactTypeFlags_Group:	
       
   676 			typeUid = KUidContactGroup;
       
   677 			break;
       
   678 		case EContactTypeFlags_OwnCard:	
       
   679 			typeUid = KUidContactOwnCard;
       
   680 			break;
       
   681 		case EContactTypeFlags_ICCEntry:
       
   682 			typeUid =  KUidContactICCEntry;
       
   683 			break;
       
   684 		case EContactTypeFlags_Template:
       
   685 			typeUid =  KUidContactTemplate;
       
   686 			break;
       
   687 		case EContactTypeFlags_CardTemplate:
       
   688 			typeUid =  KUidContactCardTemplate;
       
   689 			break;
       
   690 		default:
       
   691 			//This is error type, something wrong in database?
       
   692 			typeUid = KNullUid;
       
   693 			break;
       
   694 		}
       
   695 		
       
   696 	return typeUid;	
       
   697 	}	
       
   698 
       
   699 
       
   700 /**
       
   701 Convert Contact Type Uid to type flags bits.
       
   702 
       
   703 @param aTypeFlags the type flags get from contact table.
       
   704 
       
   705 @return type flag which put in contact type.
       
   706 */
       
   707 TInt TCntPersistenceUtility::ContactTypeUidToTypeFlags(TUid aContactTypeUid)
       
   708 	{
       
   709 	TInt contactTypeFlags = EContactTypeFlags_UnknownType;
       
   710 	switch(aContactTypeUid.iUid)
       
   711 		{
       
   712 		case KUidContactCardValue:
       
   713     		contactTypeFlags = EContactTypeFlags_ContactCard;
       
   714 			break;
       
   715 		case KUidContactGroupValue:
       
   716 		    contactTypeFlags = EContactTypeFlags_Group;	
       
   717 			break;
       
   718 		case KUidContactOwnCardValue:
       
   719 		    contactTypeFlags = EContactTypeFlags_OwnCard;	
       
   720 			break;
       
   721 		case KUidContactICCEntryValue:
       
   722 		    contactTypeFlags = EContactTypeFlags_ICCEntry;
       
   723 			break;
       
   724 		case KUidContactTemplateValue:
       
   725 		    contactTypeFlags = EContactTypeFlags_Template;
       
   726 			break;
       
   727 		case KUidContactCardTemplateValue:
       
   728 		    contactTypeFlags = EContactTypeFlags_CardTemplate;
       
   729 			break;
       
   730 		}
       
   731 		
       
   732 	return contactTypeFlags << EContactType_Shift;	
       
   733 	}	
       
   734 
       
   735 
       
   736 /**
       
   737 Get regarding column name from given fast access field type
       
   738 
       
   739 @param aFieldUid The field type uid for specific field requested.
       
   740 
       
   741 @return fast access column name for the specific field requrested.
       
   742 */
       
   743 const TDesC& TCntPersistenceUtility::GetFastAccessColumnNameById(TInt32 aFieldUid)
       
   744 	{
       
   745 	switch(aFieldUid)
       
   746 		{
       
   747 	    case KUidContactFieldGivenNameValue:
       
   748 			return KContactFirstName();
       
   749 	    case KUidContactFieldFamilyNameValue:
       
   750 			return KContactLastName();
       
   751 	    case KUidContactFieldCompanyNameValue:
       
   752 			return KContactCompanyName();
       
   753 	    case KUidContactFieldGivenNamePronunciationValue:
       
   754 			return KContactFirstNamePrn();
       
   755 	    case KUidContactFieldFamilyNamePronunciationValue:
       
   756 			return KContactLastNamePrn();
       
   757 	    case KUidContactFieldCompanyNamePronunciationValue:
       
   758 			return KContactCompanyNamePrn();
       
   759 		default:
       
   760 			return KNullDesC();
       
   761 		}
       
   762 	}
       
   763 
       
   764 
       
   765 /**
       
   766 Cleanup stack call up to handle RPointerArray.
       
   767 
       
   768 @param aArray Pointer to an RPointerArray<CContactItemField> instance.
       
   769 
       
   770 @return None.
       
   771 */
       
   772 void TCntPersistenceUtility::ResetAndDestroyRPointerArray(TAny *aArray)
       
   773 	{
       
   774 	RPointerArray<CContactItemField> *parray = static_cast< RPointerArray<CContactItemField> * >(aArray);
       
   775 	parray->ResetAndDestroy();			
       
   776 	parray->Close();
       
   777 	}
       
   778