/**
Utility method used to read text fields from blob and fill item field set,Provides a mechanism to restore a 
contact item field set from text blob field within contact database.
Blob informations are stored based on contact item field. At restore, a reference to a contact item field set
is provided. For every contact item field in the item field set, a text restore is made.

@param		aFieldSet Reference to CContactItemFieldSet. Item field set that has to be filled with informations from blob
@param		aHeaderStore Stream store containing the header informations
@param		aId Root id for the header stream store
@param		aValuesStore Read stream used to read text fields from text blob
@param		aViewDef View definition indicating which fields have to be read from blob
@param		aTemplate Template indicating if current field set should be filled based on a template
*/	
void TCntPersistenceUtility::RestoreTextL(CContactItemFieldSet& aFieldSet, CStreamStore& aHeaderStore, TStreamId aId, HBufC* textStream, const CContactItemViewDef& aViewDef, const CContactItem* aTemplate)
	{
	const TBool KIncludeFields = ( aViewDef.Use() == CContactItemViewDef::EIncludeFields );
	
	if (KIncludeFields && aViewDef.Count() == 0)
		{
		// If view definition does not contain any field we don't do anything (don't read from 
		// blob). We simply return from method without doing anything.
		// This is not an error condition
		return;	
		}
		
	RStoreReadStream stream;
	stream.OpenLC(aHeaderStore,aId);
	
	TCardinality fieldCount;
	stream>>fieldCount;
	
	TInt textFieldIndex=0;

	for (TInt ii = 0; ii < fieldCount; ++ii)
		{
		// Restore text for every CContactItemField in provided CContactItemFieldSet.
		CContactItemField* field = CContactItemField::NewLC();
		
		if(aTemplate)
		    {
    		field->RestoreFieldTypesL(stream, &(aTemplate->CardFields()));
		    }
		else
		    {
    		field->RestoreFieldTypesL(stream, NULL);
		    }    
		    
		ASSERT(field->StorageType() == KStorageTypeText);

		TBool fieldDefined = ETrue;
		if(!aViewDef.MatchesAll())
			{
			fieldDefined = (aViewDef.Find(field->ContentType()) != KErrNotFound);
			}

		if ((!((fieldDefined && KIncludeFields) || (!fieldDefined && !KIncludeFields))) || 
			(field->IsHidden() && aViewDef.Mode() == CContactItemViewDef::EMaskHiddenFields))
			{
    		CleanupStack::PopAndDestroy(field); 	
			}
		else
		    {
    		field->RestoreTextL(textStream, textFieldIndex);
			aFieldSet.AddL(*field);
    		CleanupStack::Pop(field); 	
		    }	
		    
        ++textFieldIndex;
		}
	CleanupStack::PopAndDestroy(&stream);	
	}
TBool CPackagerCntComparator::DoCompareCContactItemField(const CContactItemField& anItemField1, const CContactItemField& anItemField2) const
/** Compares two CContactItemField items. 

@param anItemField1 The first CContactItemField to be compared.
@param anItemField2 The second CContactItemField to be compared.
@return ETrue if the two items are equal, EFalse otherwise. */
	{
	
	// todo VERIFY COPNTENT TYPE LEAVE
	return(Compare(anItemField1.ContentType(), anItemField2.ContentType())	&
		DoCompareCContactItemFieldStorageTypeL(anItemField1, anItemField2)	&
		DoCompareTPtrC(anItemField1.Label(), anItemField2.Label())			&
		DoCompareTInt(anItemField1.Id(), anItemField2.Id())				&
		DoCompareCContactItemFieldAttribute(anItemField1, anItemField2)		&
		DoCompareCContactItemExtendedFieldAttribute(anItemField1, anItemField2));
		// TemplateFieldId;	Not Exported!!!!!
		// DoCompareTIntL(anItemField1.TemplateFieldId(), anItemField2.TemplateFieldId());
	}
Example #3
0
TInt CAgentAddressbook::GetTypeFromItemField(const CContactItemField& aField)
	{
	const CContentType& contType = aField.ContentType();

#ifdef _LOGGING
	__FLOG(_L("ContentType:"));
	for (TInt i = 0; i < contType.FieldTypeCount(); i++)
		{
		TFieldType type = contType.FieldType(i);
		TBuf<20> buf;
		buf.AppendNum(type.iUid, EHex);
		__FLOG(buf);
		}
#endif

	if (contType.ContainsFieldType(KUidContactFieldGivenName))
		return EFirstName;

	if (contType.ContainsFieldType(KUidContactFieldFamilyName))
		return ELastName;

	if (contType.ContainsFieldType(KUidContactFieldCompanyName))
		return ECompanyName;

	if (contType.ContainsFieldType(KUidContactFieldJobTitle))
		return EJobTitle;

	if (contType.ContainsFieldType(KUidContactFieldVCardMapCELL))
		return EMobileTelephoneNumber;

	if (contType.ContainsFieldType(KUidContactFieldVCardMapVOICE))
		{
		if (contType.ContainsFieldType(KUidContactFieldVCardMapWORK))
			return EBusinessTelephoneNumber;
		return EHomeTelephoneNumber;
		}

	if (contType.ContainsFieldType(KUidContactFieldVCardMapFAX))
		{
		if (contType.ContainsFieldType(KUidContactFieldVCardMapWORK))
			return EBusinessFaxNumber;
		return EHomeFaxNumber;
		}

	if (contType.ContainsFieldType(KUidContactFieldPostcode))
		{
		if (contType.ContainsFieldType(KUidContactFieldVCardMapWORK))
			return EBusinessAddressPostalCode;
		if (contType.ContainsFieldType(KUidContactFieldVCardMapHOME))
			return EHomeAddressPostalCode;
		return EOtherAddressPostalCode;
		}

	if (contType.ContainsFieldType(KUidContactFieldAddress))
		{
		if (contType.ContainsFieldType(KUidContactFieldVCardMapWORK))
			return EBusinessAddressPostalCode;
		if (contType.ContainsFieldType(KUidContactFieldVCardMapHOME))
			return EHomeAddressPostalCode;
		return EOtherAddressStreet;
		}

	if (contType.ContainsFieldType(KUidContactFieldLocality))
		{
		if (contType.ContainsFieldType(KUidContactFieldVCardMapWORK))
			return EBusinessAddressCity;
		if (contType.ContainsFieldType(KUidContactFieldVCardMapHOME))
			return EHomeAddressCity;
		return EOtherAddressCity;
		}

	if (contType.ContainsFieldType(KUidContactFieldRegion))
		{
		if (contType.ContainsFieldType(KUidContactFieldVCardMapWORK))
			return EBusinessAddressState;
		if (contType.ContainsFieldType(KUidContactFieldVCardMapHOME))
			return EHomeAddressState;
		return EOtherAddressState;
		}

	if (contType.ContainsFieldType(KUidContactFieldCountry))
		{
		if (contType.ContainsFieldType(KUidContactFieldVCardMapWORK))
			return EBusinessAddressCountry;
		if (contType.ContainsFieldType(KUidContactFieldVCardMapHOME))
			return EHomeAddressCountry;
		return EOtherAddressCountry;
		}

	return EUnknown;
	}
/**
Filling content for the given view contact object.

@param aViewContact reference to the view contact object to be filled
@param aSqlStmt the sql statement which contains the retrieved content for the view object. 
*/
void CCntPplViewSession::FillViewItemL(CViewContact& aViewContact, RSqlStatement& aSqlStmt, const TContactViewPreferences& aViewPrefs)
	{
	if(iIsFastAccessFieldsOnly)
		{
		//The view gets fields only from fast access columns	
		const TInt KTextDefCount = iTextDef->Count();
		for(TInt index = 0; index < KTextDefCount; ++index)
			{
			const TDesC& KColumnName = TCntPersistenceUtility::GetFastAccessColumnNameById(iTextDef->At(index).iFieldType.iUid);
			ASSERT(KColumnName.Length() > 0);
			
			TPtrC fieldPtrC = aSqlStmt.ColumnTextL(iCntSqlStatement->ParameterIndex(KColumnName));
   			AddFieldInViewContactL(aViewContact, fieldPtrC, aViewPrefs);
			} //for
		}
	else
		{
		TBool searchFastAccessFields = EFalse;
		
		// iTextDef contains the fields that should be included in the view.
		// The array of all the field objects in a contact item is returned from
		// the Contacts table.  
		RPointerArray<CContactItemField> fields;
		CleanupStack::PushL(TCleanupItem(TCntPersistenceUtility::ResetAndDestroyRPointerArray, &fields));
		
		TPtrC8 textHeader;
		aSqlStmt.ColumnBinary(iCntSqlStatement->ParameterIndex(KContactTextFieldHeader()), textHeader);
		RDesReadStream textHeaderStream(textHeader);
		CleanupClosePushL(textHeaderStream);
        CEmbeddedStore* textHeaderStore = CEmbeddedStore::FromLC(textHeaderStream);
        
    	RStoreReadStream textHeaderStoreStream;
    	textHeaderStoreStream.OpenLC(*textHeaderStore,textHeaderStore->Root());
        
		TPtrC textFieldPtrC = aSqlStmt.ColumnTextL(iCntSqlStatement->ParameterIndex(KContactTextFields()));
		HBufC* textFieldsBuf = textFieldPtrC.AllocLC();
			
		TCntPersistenceUtility::ReadTextBlobL(textHeaderStoreStream, textFieldsBuf, *iTextDef, iContactProperties.SystemTemplateL(), fields, searchFastAccessFields);
		CleanupStack::PopAndDestroy(4, &textHeaderStream); //textHeaderStore, textHeaderStream, textHeaderStoreStream, textFieldsBuf
		
		// Loop through fields, checking for fields from fast access fields, and add 
		// the fields to the view contact object.
		const TInt KFieldsNumMax = fields.Count();
		for(TInt fieldsIndex = 0; fieldsIndex < KFieldsNumMax; ++fieldsIndex)
			{
			// this doesn't own the instance stored in fields array.
			CContactItemField* itemField = fields[fieldsIndex];

			if(itemField == NULL)
				{
				aViewContact.AddFieldL(KNullDesC);
				continue;
				}

			// The array of fields retrieved from the text fields blob does not
			// contain the text data Fast Access fields. If the searchFastAccessFields 
			// flags have been set then get the data from Fast Access columns
			// before adding the data to the view.
			TPtrC fieldText;
			if(searchFastAccessFields && itemField->ContentType().FieldTypeCount() > 0)
				{
				//Check the field name of the first field type(key field type) 
				//in the field's field types array
    			const TDesC& KColumnName = TCntPersistenceUtility::GetFastAccessColumnNameById(itemField->ContentType().FieldType(0).iUid);
				if(KColumnName.Length() > 0)
					{
					//this is a fast access field.
					fieldText.Set(aSqlStmt.ColumnTextL(iCntSqlStatement->ParameterIndex(KColumnName)));
					}
				else
					{
					fieldText.Set(itemField->TextStorage()->Text());
					}					
				}
			else
				{
				fieldText.Set(itemField->TextStorage()->Text());
				}
			
			AddFieldInViewContactL(aViewContact, fieldText, aViewPrefs);
			}
		
		CleanupStack::PopAndDestroy(&fields);
		}
	}
/**
Reads the first text field from text fields blob based on aFieldType.  

1. If aFieldType is KUidContactFieldMatchAll: 
If the first text field found in the text fields blob is an Email field, 
then the email address is returned in aText and found exit with ETrue returned, 
If an email address is not returned, the first text field found in the text 
field blob is returned, however it is considered as the best effort text, so 
the calling function will return EFalse indicate the caller to found suitable
text in Fast Access fields.

2. If aFieldType is other than KUidContactFieldMatchAll: 
Find the first text field matching aFieldType from given text fields buffer and 
returned the field content in aText with ETrue returned, returning EFalse if it 
can't find matched field.

@param aHeaderStream The read stream contains text field header
@param aTextFieldsBuf The text fields blob buffer.
@param aSystemTemplate Reference to system template class.
@param aFieldType Field type to match the field
@param aText Text found in text fields buffer based on a FieldType. 
*/
TBool TCntPersistenceUtility::FindTxtFieldInTextBlobL(RReadStream& aHeaderStream, HBufC* aTextFieldsBuf, const CContactTemplate& aSystemTemplate, const TFieldType& aFieldType, TDes& aText)
	{
	// Extract the number of fields from the header stream.
	TCardinality headerFieldCount;
	aHeaderStream>>headerFieldCount;
	
	TInt txtFldIndex = 0;
	CContactItemField* itemField = NULL;
	// Assign to a TInt variable to avoid using the overloaded int operator on
	// each iteration - improves performance.
	TInt max = headerFieldCount;
	
	// Loop through the header fields and try to retrieve the text from the
	// searchable text buffer.
	for(TInt hdrFldIndex = 0; hdrFldIndex < max; ++hdrFldIndex)
		{
		itemField = CContactItemField::NewLC();

		// Using both header-fields and template-fields, setup the field to hold
		// the correct type UIDs.
		itemField->RestoreFieldTypesL(aHeaderStream, &aSystemTemplate.CardFields());

		// Only restore text fields - ignore all other fields.
		if(itemField->StorageType() == KStorageTypeText)
			{
			if(aFieldType == KUidContactFieldMatchAll)
				{
				// Restore the field text from the searchable text buffer.
				itemField->RestoreTextL(aTextFieldsBuf, txtFldIndex);
				
				if(itemField->ContentType().ContainsFieldType(KUidContactFieldEMail))
					{
					if(CopyMinFieldText(itemField->TextStorage()->Text(), aText))
						{
						CleanupStack::PopAndDestroy(itemField); 
						return ETrue;
						}
					}
				else if(aText.Length() == 0 && itemField->TextStorage()->Text().Length() > 0)
					{
					// If there is text in the field then make a copy of the first
					// KTextFieldMinimalLength characters.
					CopyMinFieldText(itemField->TextStorage()->Text(), aText);
					} //else if
				} 
			else if(itemField->ContentType().ContainsFieldType(aFieldType))
				{
				// Restore the field text from the searchable text buffer.
				itemField->RestoreTextL(aTextFieldsBuf, txtFldIndex);
				itemField->GetFieldText(aText);
				//CopyMinFieldText(itemField->TextStorage()->Text(), aText);	
				CleanupStack::PopAndDestroy(itemField); 
				return ETrue;
				} //else if
				
			++txtFldIndex;
			} //if
		CleanupStack::PopAndDestroy(itemField);
		} // for
	return EFalse;
	}
/**
Utility class to read text blob from given header stream and text buffer, and
return an array of contact item fields defined in aTextDef.

The method loops through the fields of the given text definition and adds (text)
fields from text buffer which match the text definition field types.

@param aHeaderStream the read stream contains text header blob data 
@param aTextBuffer  text buffer storing text fields.
@param aTextDef The text defintion containing the fields IDs required in the
				view contact.
@param aSearchFastAccessFields Return value indicating that additional fields can
							   be found in the Fast Access fields.

@return An array of contact item fields.
*/	
void TCntPersistenceUtility::ReadTextBlobL(RReadStream& aHeaderStream, const HBufC* aTextBuffer, const CContactTextDef& aTextDef, const CContactTemplate& aSystemTemplate, RPointerArray<CContactItemField>& aFields, TBool& aSearchFastAccessFields)
	{
	TInt max = aTextDef.Count();
	for(TInt i=0; i<max; ++i)
		{
		aFields.AppendL(NULL);
		}	
	
	// Extract the number of fields from the header stream.
	TCardinality headerFieldCount;
	aHeaderStream>>headerFieldCount;
	
	TInt textFieldIndex = 0;
	const TInt KMaxTextDefFlds = aTextDef.Count();
	
	CContactItemField* itemField = CContactItemField::NewLC();
	for(TInt hdrFldIndex = 0; hdrFldIndex < headerFieldCount; ++hdrFldIndex)
		{
		// Internalization in RestoreFieldTypesL() moves headerStream on to
		// point to the next element.  RestoreFieldTypesL() knows how to format
		// a header element.
		itemField->RestoreFieldTypesL(aHeaderStream, &aSystemTemplate.CardFields());
	
		// Loop through all the text definition fields.
		for(TInt defIndex = 0; defIndex < KMaxTextDefFlds; ++defIndex)
			{
			// Check if text definition field and current header field types
			// match.
			if((itemField->ContentType().ContainsFieldType(aTextDef.At(defIndex).iFieldType) 
				|| aTextDef.At(defIndex).iFieldType == KUidContactFieldMatchAll) 
				&& itemField->StorageType() == KStorageTypeText)
				{
				// They do match but take care of duplicates.
				if(aFields[defIndex] == NULL)
					{
					itemField->ResetStore();
					// Restore field text from the searchable buffer.
					itemField->RestoreTextL(const_cast<HBufC*>(aTextBuffer), textFieldIndex);
					// Although there's an entry there may be more tables to
					// read.
					if(itemField->TextStorage()->Text().Length() == KNullBlobTextField().Length()
						&& itemField->TextStorage()->Text().Compare(KNullBlobTextField) == 0)
						{
						aSearchFastAccessFields = ETrue;
						}
						
					// Assign the array in correct sequence then clone a new one
					// to continue the search in case there's more than one of
					// this field type.			
					aFields[defIndex] = CContactItemField::NewL(*itemField);
					}
				}
			}
			
		if(itemField->StorageType() == KStorageTypeText)
			{
			++textFieldIndex;
			}
			
		// Always one left over.
		itemField->Reset();
		}
		CleanupStack::PopAndDestroy(itemField);
	}