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