plugins/contacts/symbian/contactsmodel/src/cntfield.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /*
       
     2 * Copyright (c) 1997-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 #include <s32std.h>
       
    20 
       
    21 #include "cntstd.h"
       
    22 #include <cntdef.h>
       
    23 #include <cntfield.h>
       
    24 #include <cntfldst.h>
       
    25 
       
    26 #include <cntitem.h>
       
    27 #include <versit.h>
       
    28 #include "cntprof.h"
       
    29 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    30 #include "cntfieldheader.h"
       
    31 #include "cnthint.h"
       
    32 #include "cntfield_internal.h"
       
    33 #endif
       
    34 
       
    35 //
       
    36 // class TContactFieldAtts
       
    37 //
       
    38 const TUint32 KAttribsMask		    = 0xf0000fff;
       
    39 const TUint32 KExtendedAttribsMask	= 0x000ff000;
       
    40 const TUint32 KStorageTypeMask	    = 0x00f00000;
       
    41 
       
    42 const TUint32 KTypeBitShift		    = 20;
       
    43 const TUint32 KExtendedAttsBitShift = 12;
       
    44 
       
    45 /** Set contact field attributes.
       
    46 
       
    47 @param aAttribs contact field arributes to be set.
       
    48 @internalTechnology
       
    49 */
       
    50 void TContactFieldAtts::SetAttribs(TUint32 aAttribs)
       
    51 	{
       
    52 	iStorage |= aAttribs;
       
    53 	}
       
    54 	
       
    55 /** Set contact field extended arributes.
       
    56 
       
    57 @param aExtendedAttribs contact field extended arributes to be set.
       
    58 @internalTechnology
       
    59 */
       
    60 void TContactFieldAtts::SetExtendedAttribs(TUint32 aExtendedAttribs)
       
    61 	{
       
    62 	iStorage |= aExtendedAttribs << KExtendedAttsBitShift;
       
    63 	}
       
    64 
       
    65 /** Set storage type.
       
    66 
       
    67 @param aType storage type to set.
       
    68 @internalTechnology
       
    69 */
       
    70 void TContactFieldAtts::SetType(TStorageType aType)
       
    71 	{
       
    72 	iStorage |= aType << KTypeBitShift;
       
    73 	}
       
    74 
       
    75 /** Get contact field arributes.
       
    76 
       
    77 @return contact field arributes.
       
    78 @internalTechnology
       
    79 */
       
    80 TUint32 TContactFieldAtts::Attribs() const
       
    81 	{
       
    82 	return (iStorage & KAttribsMask);
       
    83 	}
       
    84 	
       
    85 /** Get contact field extended arributes.
       
    86 
       
    87 @return contact field extended arributes.
       
    88 @internalTechnology
       
    89 */
       
    90 TUint32 TContactFieldAtts::ExtendedAttribs() const
       
    91 	{
       
    92 	return (iStorage & KExtendedAttribsMask) >> KExtendedAttsBitShift;
       
    93 	}
       
    94 	
       
    95 /** Get contact field storage type.
       
    96 
       
    97 @return contact field storage type.
       
    98 @internalTechnology
       
    99 */
       
   100 TStorageType TContactFieldAtts::Type() const
       
   101 	{
       
   102 	return (iStorage & KStorageTypeMask) >> KTypeBitShift;
       
   103 	}
       
   104 	
       
   105 /** Internalize implementation.
       
   106 
       
   107 @internalTechnology
       
   108 */
       
   109 void TContactFieldAtts::InternalizeL(RReadStream& aStream)
       
   110 	{
       
   111 	iStorage=aStream.ReadUint32L();
       
   112 	}
       
   113 	
       
   114 /** Externalize implementation.
       
   115 
       
   116 @internalTechnology
       
   117 */
       
   118 void TContactFieldAtts::ExternalizeL(RWriteStream& aStream) const
       
   119 	{
       
   120 	aStream.WriteUint32L(iStorage);
       
   121 	}
       
   122 
       
   123 
       
   124 //
       
   125 // class CContentType
       
   126 //
       
   127    
       
   128 EXPORT_C CContentType::~CContentType()
       
   129 /** Frees all resources owned by the content type object, prior 
       
   130 to its destruction. */
       
   131     {
       
   132 	delete iFieldTypes;
       
   133 	}
       
   134       
       
   135 CContentType::CContentType()
       
   136     {
       
   137 	}
       
   138       
       
   139 CContentType::CContentType(TUid aMapping) : iMapping(aMapping)
       
   140 	{
       
   141 	}
       
   142 	
       
   143 /** Constructs a new content type based on a RReadStream.
       
   144 
       
   145 @param aStream RReadStream containing object to internalize.
       
   146 @return Pointer to the newly created CContentType. This is left on the cleanup stack. 
       
   147 @internalTechnology
       
   148 */
       
   149 CContentType* CContentType::NewLC(RReadStream& aStream)
       
   150 	{ // static
       
   151 	CContentType* type = NewL();
       
   152 	CleanupStack::PushL(type);
       
   153 	type->InternalizeL(aStream);
       
   154 	
       
   155 	return type;
       
   156 	}		
       
   157 
       
   158 EXPORT_C CContentType* CContentType::NewL()
       
   159 /** Allocates and constructs a new default CContentType.
       
   160 
       
   161 The object has no field types and the mapping is set to KNullUid
       
   162 
       
   163 @return Pointer to the newly created content type object. */
       
   164 	{
       
   165 	CContentType* self=new(ELeave) CContentType(KNullUid);
       
   166 	CleanupStack::PushL(self);
       
   167 	self->ConstructL();
       
   168 	CleanupStack::Pop();	// self
       
   169 	return(self);
       
   170 	}
       
   171 
       
   172 EXPORT_C CContentType* CContentType::NewL(TFieldType aFieldType,TUid aMapping)
       
   173 /** Allocates and constructs a new CContentType with a single field 
       
   174 type and a mapping.
       
   175 
       
   176 @param aFieldType The field type to add to the content type.
       
   177 @param aMapping The mapping.
       
   178 @return Pointer to the newly created content type object. */
       
   179 	{
       
   180 	CContentType* self=new(ELeave) CContentType(aMapping);
       
   181 	CleanupStack::PushL(self);
       
   182 	self->ConstructL();
       
   183 	self->AddFieldTypeL(aFieldType);
       
   184 	CleanupStack::Pop();	// self
       
   185 	return(self);
       
   186 	}
       
   187 
       
   188 EXPORT_C CContentType* CContentType::NewL(const CContentType &aContentType)
       
   189 /** Allocates and constructs a new CContentType based on another one.
       
   190 
       
   191 @param aContentType The CContentType on which to base the new one.
       
   192 @return Pointer to the newly created content type object. */
       
   193 	{ // static
       
   194 	CContentType* self=new(ELeave) CContentType;
       
   195 	CleanupStack::PushL(self);
       
   196 	self->ConstructL();
       
   197 	self->CloneL(aContentType);
       
   198 	CleanupStack::Pop();	// self
       
   199 	return self;
       
   200 	}
       
   201  
       
   202 void CContentType::ConstructL()
       
   203 	{
       
   204 	iFieldTypes=new(ELeave) CArrayFixFlat<TUid>(2);
       
   205 	}
       
   206 
       
   207 EXPORT_C void CContentType::AddFieldTypeL(TFieldType aFieldType)
       
   208 /** Appends a field type to the content type's list of field types.
       
   209 
       
   210 Note that certain combinations of field types are not valid and should not be
       
   211 used.
       
   212 
       
   213 @param aFieldType The field type to append to the list of field types. */
       
   214 	{
       
   215 	const TInt KMaxFieldTypes=15;
       
   216 	if (iFieldTypes->Count()==KMaxFieldTypes)
       
   217 		{
       
   218 		User::Leave(KErrOverflow);
       
   219 		}
       
   220     		
       
   221    	iFieldTypes->AppendL(aFieldType);
       
   222 	}
       
   223 
       
   224 EXPORT_C void CContentType::RemoveFieldType(TFieldType aFieldType)
       
   225 /** Removes a field type from the list of field types.
       
   226 
       
   227 @param aFieldType The field type to remove from the list of field types. */
       
   228 	{
       
   229 	for(TInt loop=0;loop<iFieldTypes->Count();loop++)
       
   230 		if ((*iFieldTypes)[loop]==aFieldType)
       
   231 			{
       
   232 			iFieldTypes->Delete(loop);
       
   233 			break;
       
   234 			}
       
   235 	}
       
   236 
       
   237 EXPORT_C void CContentType::SetMapping(TUid aMapping)
       
   238 /** Sets the vCard mapping.
       
   239 
       
   240 @param aMapping The new vCard mapping for the content type. */
       
   241 	{
       
   242 	iMapping=aMapping;
       
   243 	}
       
   244 
       
   245 void CContentType::CloneL(const CContentType &aContentType)
       
   246 	{
       
   247     iMapping=aContentType.iMapping;
       
   248 	if (aContentType.iFieldTypes)
       
   249 		for(TInt loop=0;loop<aContentType.iFieldTypes->Count();loop++)
       
   250 			AddFieldTypeL((*aContentType.iFieldTypes)[loop]);
       
   251 	}
       
   252 
       
   253 EXPORT_C TInt CContentType::FieldTypeCount() const
       
   254 /** Gets the number of field types in the content type's list of field types.
       
   255 
       
   256 @return The number of field types in the content type. */
       
   257 	{
       
   258 	return(iFieldTypes->Count());
       
   259 	}
       
   260 
       
   261 EXPORT_C TFieldType CContentType::FieldType(TInt aIndex) const
       
   262 /** Gets the indexed field type.
       
   263 
       
   264 @param aIndex Index into the list of field types. The position is relative 
       
   265 to zero; i.e. zero implies the first element in the array. This value must 
       
   266 be non-negative and less than the number of objects currently within the array 
       
   267 otherwise the operator raises a panic.
       
   268 @return The indexed field type. */
       
   269 	{
       
   270 	__ASSERT_DEBUG(aIndex<iFieldTypes->Count(),Panic(ECntPanicFieldTypeIndex));
       
   271 	return((*iFieldTypes)[aIndex]);
       
   272 	}
       
   273 
       
   274 EXPORT_C TUid CContentType::Mapping() const
       
   275 /** Gets the vCard mapping.
       
   276 
       
   277 @return The vCard mapping. */
       
   278 	{
       
   279 	return(iMapping);
       
   280 	}
       
   281 
       
   282 EXPORT_C TBool CContentType::ContainsFieldType(TFieldType aFieldType) const
       
   283 /** Tests whether the content type object contains the specified field type UID 
       
   284 either as the mapping value or in its list of field types.
       
   285 
       
   286 @param aFieldType The field type of interest.
       
   287 @return ETrue if the CContentType contains the specified field type. EFalse 
       
   288 if not. */
       
   289 	{
       
   290 	if (iMapping==aFieldType)
       
   291 		return(ETrue);
       
   292 	for(TInt loop=0;loop<iFieldTypes->Count();loop++)
       
   293 		if ((*iFieldTypes)[loop]==aFieldType)
       
   294 			return(ETrue);
       
   295 	return(EFalse);
       
   296 	}
       
   297 
       
   298 void CContentType::InternalizeAdditionalUidsL(TInt aCount,RReadStream& aStream)
       
   299 	{
       
   300 	for (TInt ii=0;ii<aCount;ii++) 
       
   301 		iFieldTypes->AppendL(TUid::Uid(aStream.ReadInt32L()));
       
   302 	}
       
   303 
       
   304 EXPORT_C TBool CContentType::SupportsMultipleLines() const
       
   305 /** Tests whether the content type supports multiple lines of text. If the content 
       
   306 type object contains a field type which supports this, either in its list 
       
   307 of field types, or as its mapping, the function returns ETrue. Examples of 
       
   308 such field types are address fields (type KUidContactFieldAddress) and note 
       
   309 fields (type KUidContactFieldNote).
       
   310 
       
   311 @return ETrue if the CContentType supports multiple lines of text. EFalse 
       
   312 if not. */
       
   313 	{
       
   314 	return(ContainsFieldType(KUidContactFieldAddress) || ContainsFieldType(KUidContactFieldNote));
       
   315 	}
       
   316 
       
   317 EXPORT_C TBool CContentType::operator==(const CContentType &aType) const
       
   318 /** Compares two content type objects for equality. 
       
   319 Two content type objects are equal according to this method if all following 
       
   320 conditions are met:
       
   321 - vCard property mapping matches
       
   322 - same number of field types
       
   323 - main field type matches
       
   324 - additional field types and vCard property parameter mappings match
       
   325  
       
   326 @param aType The content type to compare with this CContentType.
       
   327 +@return ETrue if aType is equal with current content type. */
       
   328 	{
       
   329 	// Compare vCard property mapping.
       
   330 	if (Mapping() != aType.Mapping())
       
   331 		{
       
   332 		return EFalse;
       
   333 		}
       
   334 	
       
   335 	// Compare field type counts.
       
   336 	const TInt typeCount = FieldTypeCount();
       
   337 	if (typeCount != aType.FieldTypeCount())
       
   338 		{
       
   339 		return EFalse;
       
   340 		}
       
   341 	if (typeCount <= 0)
       
   342 		{
       
   343 		// Nothing more to compare.
       
   344 		return ETrue;
       
   345 		}
       
   346 	
       
   347 	// Compare main field type.
       
   348 	if (FieldType(0) != aType.FieldType(0))
       
   349 		{
       
   350 		return EFalse;
       
   351 		}
       
   352 	
       
   353 	// Compare additional field types and vCard property parameter mappings.
       
   354 	for (TInt lhsIndex = 1; lhsIndex < typeCount; ++lhsIndex)
       
   355 		{
       
   356 		TInt rhsIndex = 1;
       
   357 		for (rhsIndex = 1; rhsIndex < typeCount; ++rhsIndex)
       
   358 			{
       
   359 			if (FieldType(lhsIndex) == aType.FieldType(rhsIndex))
       
   360 			    break;
       
   361 			}
       
   362 		if (rhsIndex == typeCount)
       
   363 			{
       
   364 			// No match found.
       
   365 			return EFalse;
       
   366 			}
       
   367 		}
       
   368 	
       
   369 	return ETrue;
       
   370 	}
       
   371 
       
   372 EXPORT_C TBool CContentType::IsEqual(const CContentType &aType) const
       
   373 /** Compares two content type objects for equality.
       
   374 Two content type objects are equal according to this method if all following 
       
   375 conditions are met:
       
   376 - vCard property mapping matches
       
   377 - same number of field types
       
   378 - main field type matches
       
   379 - additional field types and vCard property parameter mappings match
       
   380  
       
   381 @param aType The content type to compare with this CContentType.
       
   382 @return ETrue if aType is equal with current content type. */
       
   383 	{
       
   384 	// Compare vCard property mapping.
       
   385 	if (iMapping!=aType.iMapping)
       
   386 		{
       
   387 		return(EFalse);	
       
   388 		}
       
   389 	
       
   390 	// Compare field type counts.
       
   391 	const TInt typeCount = aType.FieldTypeCount();
       
   392 	if (FieldTypeCount()!= typeCount)
       
   393 		{
       
   394 		return(EFalse);	
       
   395 		}
       
   396 		
       
   397     if (typeCount <= 0)
       
   398         {
       
   399         // Nothing more to compare.
       
   400         return ETrue;
       
   401         }
       
   402 			
       
   403     // Compare main field type.
       
   404     if (FieldType(0) != aType.FieldType(0))
       
   405         {
       
   406         return EFalse;
       
   407         }
       
   408 
       
   409     // Compare additional field types and vCard property parameter mappings.
       
   410     for (TInt leftIndex = 1; leftIndex < typeCount; ++leftIndex)
       
   411         {
       
   412         TUint rightIndex = 1;
       
   413         for (rightIndex = 1; rightIndex < typeCount; ++rightIndex)
       
   414             {
       
   415             if (FieldType(leftIndex) == aType.FieldType(rightIndex))
       
   416                 break;
       
   417             }
       
   418         if (rightIndex == typeCount)
       
   419             {
       
   420             // No match found.
       
   421             return EFalse;
       
   422             }
       
   423         }
       
   424 
       
   425     return ETrue;
       
   426    	}
       
   427   	
       
   428 void CContentType::Reset()
       
   429 	{
       
   430 	iMapping=TUid::Uid(0);
       
   431 	iFieldTypes->Reset();
       
   432 	}
       
   433 
       
   434 
       
   435 /*
       
   436  * Determine if content types are suitable to match for synchronization purpose. 
       
   437  * Some properties are subject to specific processing depending of the <code>CContentType</code> Mapping. 
       
   438  * Notably: VOICE, PREF, VoiceDial and SpeedDial. 
       
   439  * VOICE is a a default property parameter for all TEL properties.
       
   440  *
       
   441  * @param		"const CContentType& aType"
       
   442  *				The content type to compare with this
       
   443  *				<code>CContentType</code>. Beware, to do a proper comparison,
       
   444  *				the <code>aType</code> parameter must not contains VoiceDial or SpeedDial properties.
       
   445  *				Otherwise the fields will not match.				  
       
   446  *
       
   447  * @return 		"TBool"
       
   448  *				<code>ETrue</code> if <code>aType</code> match this content type.
       
   449  *				Field types do not need to be in the same order in the 
       
   450  *				list of field types for a match to be made.
       
   451  */
       
   452 EXPORT_C TBool CContentType::IsEqualForSyncUpdate(const CContentType& aType) const
       
   453 /** Tests whether the content types are suitable to match for synchronisation purpose. 
       
   454 
       
   455 @param aType The content type to compare with this CContentType.
       
   456 @return ETrue if aType is an identical content type
       
   457  */
       
   458 	{
       
   459 	if (iMapping!=aType.iMapping)
       
   460 		return(EFalse);	
       
   461 
       
   462 	switch (iMapping.iUid)
       
   463 		{
       
   464 	case KIntContactFieldVCardMapTEL:
       
   465 		{
       
   466 		TInt countModifier=0;
       
   467 		TInt loop=0;
       
   468 
       
   469 		if (aType.ContainsFieldType(KUidContactFieldVCardMapVOICE))
       
   470 			{
       
   471 			++countModifier;
       
   472 			}
       
   473 
       
   474 		if (aType.ContainsFieldType(KUidContactFieldVCardMapPREF))
       
   475 			{
       
   476 			++countModifier;
       
   477 			}
       
   478 		
       
   479 		if (ContainsFieldType(KUidContactFieldVCardMapVOICE))
       
   480 			{
       
   481 			--countModifier;
       
   482 			}
       
   483 
       
   484 		if (ContainsFieldType(KUidContactFieldVCardMapPREF))
       
   485 			{
       
   486 			--countModifier;
       
   487 			}
       
   488 
       
   489 		if (ContainsFieldType(KUidContactsVoiceDialField))
       
   490 			{
       
   491 			--countModifier;
       
   492 			}
       
   493 
       
   494 		//look for speed dial property only in db field
       
   495 		for(loop=0;loop<iFieldTypes->Count();loop++)
       
   496 			{
       
   497 			TInt uid = (*iFieldTypes)[loop].iUid;
       
   498 			if (uid >= KUidSpeedDialOneValue && uid <= KUidSpeedDialNineValue)
       
   499 				{
       
   500 				--countModifier;
       
   501 				break; //only one speed dial property allowed for a field
       
   502 				}
       
   503 			}
       
   504 	
       
   505 		//now check for field count	
       
   506 		if ((FieldTypeCount()+countModifier)!=aType.FieldTypeCount())
       
   507 			{
       
   508 			return(EFalse);
       
   509 			}
       
   510 				
       
   511 		//Check that all type from the imported field match a type in this field but VOICE and PREF
       
   512 		for(loop=0;loop<aType.FieldTypeCount();loop++)
       
   513 			{
       
   514 			if (!ContainsFieldType(aType.FieldType(loop)))
       
   515 				{
       
   516 				if (aType.FieldType(loop).iUid==KIntContactFieldVCardMapVOICE || aType.FieldType(loop).iUid==KIntContactFieldVCardMapPREF)
       
   517 					{
       
   518 					continue;
       
   519 					}
       
   520 				return(EFalse);
       
   521 				}
       
   522 			}
       
   523 		return(ETrue);
       
   524 		}
       
   525 
       
   526 	case KIntContactFieldVCardMapEMAILINTERNET:
       
   527 		{
       
   528 		TInt countModifier=0;		
       
   529 
       
   530 		if (aType.ContainsFieldType(KUidContactFieldVCardMapPREF))
       
   531 			{
       
   532 			++countModifier;
       
   533 			}
       
   534 		
       
   535 		if (ContainsFieldType(KUidContactFieldVCardMapPREF))
       
   536 			{
       
   537 			--countModifier;
       
   538 			}
       
   539 	
       
   540 		//now check for field count	
       
   541 		if ((FieldTypeCount()+countModifier)!=aType.FieldTypeCount())
       
   542 			{
       
   543 			return(EFalse);
       
   544 			}
       
   545 				
       
   546 		//Check that all type from the imported field match a type in this field but PREF
       
   547 		for(TInt loop=0;loop<aType.FieldTypeCount();loop++)
       
   548 			{
       
   549 			if (!ContainsFieldType(aType.FieldType(loop)))
       
   550 				{
       
   551 				if (aType.FieldType(loop).iUid==KIntContactFieldVCardMapPREF)
       
   552 					{
       
   553 					continue;
       
   554 					}
       
   555 				return(EFalse);
       
   556 				}
       
   557 			}
       
   558 		return(ETrue);
       
   559 		}
       
   560 	
       
   561 	case KIntContactFieldVCardMapAGENT:
       
   562 		{
       
   563 		return(ETrue);
       
   564 		}	
       
   565 
       
   566 	default:
       
   567 		return *this==aType;
       
   568 		}
       
   569 	}
       
   570 	
       
   571 void CContentType::InternalizeL(RReadStream& aStream)
       
   572 /** Internalises a CContentType object from a read stream. 
       
   573 @param aStream Stream from which the object should be internalised. */
       
   574 	{
       
   575     // TUid iMapping;
       
   576 	iMapping.iUid = aStream.ReadInt32L();
       
   577 	
       
   578 	// CArrayFix<TUid>* iFieldTypes;
       
   579 	const TInt count=aStream.ReadInt32L();
       
   580 
       
   581 	// Allocated in constructor
       
   582 	TUid tempID;
       
   583 	for(TInt index=0; index<count; ++index)
       
   584 		{
       
   585 		
       
   586 		aStream>>tempID;		
       
   587 		iFieldTypes->AppendL(tempID);
       
   588 		}
       
   589 	}
       
   590 
       
   591 void CContentType::ExternalizeL(RWriteStream& aStream) const 
       
   592 /** Externalises a CContentType object to a write stream.
       
   593 @param aStream Stream to which the object should be externalised. */
       
   594 	{
       
   595 	aStream.WriteInt32L(iMapping.iUid);
       
   596 	
       
   597 	const TInt count = iFieldTypes->Count();
       
   598 	aStream.WriteInt32L(count);	
       
   599 	for(TInt index=0; index<count; ++index)
       
   600 		{
       
   601 		aStream<<iFieldTypes->At(index);
       
   602 		}
       
   603 	}		
       
   604 
       
   605 
       
   606 //
       
   607 // class CContactItemField
       
   608 //
       
   609 
       
   610 EXPORT_C CContactItemField* CContactItemField::NewLC()
       
   611 /** Allocates and constructs a new default contact item field. 
       
   612 
       
   613 The field's storage type, content type and label are unspecified. 
       
   614 The ESynchronize attribute is set.
       
   615 
       
   616 @return Pointer to the newly created contact item field. */
       
   617 	{
       
   618     CContactItemField* self=new(ELeave) CContactItemField;
       
   619     CleanupStack::PushL(self);
       
   620 	self->iContentType=CContentType::NewL();
       
   621     return self;
       
   622 	}
       
   623 
       
   624 EXPORT_C CContactItemField* CContactItemField::NewL(TStorageType aType)
       
   625 /** Allocates and constructs a contact item field with a storage type. 
       
   626 
       
   627 The field's label and content type are unspecified.
       
   628 
       
   629 @param aType The field's storage type.
       
   630 @return Pointer to the newly created contact item field. */
       
   631 	{
       
   632     CContactItemField* self=CContactItemField::NewLC(aType);
       
   633     CleanupStack::Pop(); // self
       
   634     return self;
       
   635 	}
       
   636 
       
   637 EXPORT_C CContactItemField* CContactItemField::NewLC(TStorageType aType)
       
   638 /** Allocates and constructs a contact item field with a storage type. 
       
   639 
       
   640 The field's label and content type are unspecified.
       
   641 
       
   642 @param aType The field's storage type.
       
   643 @return Pointer to the newly created contact item field. This is left on 
       
   644 the cleanup stack. */
       
   645 	{
       
   646     CContactItemField* self=new(ELeave) CContactItemField(aType);
       
   647     CleanupStack::PushL(self);
       
   648     self->ConstructStorageL();
       
   649 	self->iContentType=CContentType::NewL();
       
   650     return self;
       
   651 	}
       
   652 
       
   653 EXPORT_C CContactItemField* CContactItemField::NewL(TStorageType aType, TFieldType aFieldType)
       
   654 /** Allocates and constructs a contact item field with a storage type 
       
   655 and a field type.
       
   656 
       
   657 The field's content type is initialised with the field type, 
       
   658 and its vCard mapping is set by default to KNullUid. The field's label is 
       
   659 unspecified.
       
   660 
       
   661 @param aType The field's storage type.
       
   662 @param aFieldType The field type as defined in cntdef.h.
       
   663 @return Pointer to the newly created contact item field. */
       
   664     { // static
       
   665     CContactItemField* self=CContactItemField::NewLC(aType,aFieldType);
       
   666     CleanupStack::Pop(); // self
       
   667     return self;
       
   668     }
       
   669 
       
   670 EXPORT_C CContactItemField* CContactItemField::NewLC(TStorageType aType, TFieldType aFieldType)
       
   671 /** Allocates and constructs a contact item field with a storage type 
       
   672 and a field type.
       
   673 
       
   674 The field's content type is initialised with the field type, 
       
   675 and its vCard mapping is set by default to KNullUid. The field's label is 
       
   676 unspecified.
       
   677 
       
   678 @param aType The field's storage type.
       
   679 @param aFieldType The field type as defined in cntdef.h.
       
   680 @return Pointer to the newly created contact item field. This is left on 
       
   681 the cleanup stack. */
       
   682     { // static
       
   683     CContactItemField* self=new(ELeave) CContactItemField(aType);
       
   684     CleanupStack::PushL(self);
       
   685     self->ConstructStorageL();
       
   686 	self->iContentType=CContentType::NewL(aFieldType);
       
   687     return self;
       
   688     }
       
   689 
       
   690 EXPORT_C CContactItemField* CContactItemField::NewL(const CContactItemField &aField)
       
   691 /** Allocates and constructs a contact item field based on another one.
       
   692 
       
   693 All details (content type, storage type, attributes and label) are copied 
       
   694 from the specified field.
       
   695 
       
   696 @param aField The contact field to copy.
       
   697 @return Pointer to the newly created contact item field. */
       
   698 	{ // static
       
   699 	CContactItemField* self=CContactItemField::NewLC(aField);
       
   700 	CleanupStack::Pop(); // self
       
   701 	return self;
       
   702 	}
       
   703 
       
   704 EXPORT_C CContactItemField* CContactItemField::NewLC(const CContactItemField &aField)
       
   705 /** Allocates and constructs a contact item field based on another one.
       
   706 
       
   707 All details (content type, storage type, attributes and label) are copied 
       
   708 from the specified field.
       
   709 
       
   710 @param aField The contact field to copy.
       
   711 @return Pointer to the newly created contact item field. This is left on 
       
   712 the cleanup stack. */
       
   713 	{ // static
       
   714 	CContactItemField* self=new(ELeave) CContactItemField(aField.StorageType());
       
   715 	CleanupStack::PushL(self);
       
   716 	self->ConstructStorageL();
       
   717 	self->CloneL(aField);
       
   718 	return self;
       
   719 	}
       
   720  
       
   721 EXPORT_C CContactItemField* CContactItemField::NewL(TStorageType aType, const CContentType &aContentType)
       
   722 /** Allocates and constructs a contact item field with a content type 
       
   723 and a storage type. 
       
   724 
       
   725 The field's label is unspecified.
       
   726 
       
   727 @param aType The field's storage type.
       
   728 @param aContentType The field's content type. 
       
   729 @return Pointer to the newly created contact item field. */
       
   730 	{ // static
       
   731 	CContactItemField* self=CContactItemField::NewLC(aType,aContentType);
       
   732 	CleanupStack::Pop(); // self
       
   733 	return self;
       
   734 	}
       
   735 
       
   736 EXPORT_C CContactItemField* CContactItemField::NewLC(TStorageType aType, const CContentType &aContentType)
       
   737 /** Allocates and constructs a contact item field with a content type 
       
   738 and a storage type. 
       
   739 
       
   740 The field's label is unspecified.
       
   741 
       
   742 @param aType The field's storage type.
       
   743 @param aContentType The field's content type. 
       
   744 @return Pointer to the newly created contact item field. This is left on 
       
   745 the cleanup stack. */
       
   746 	{ // static
       
   747 	CContactItemField* self=new(ELeave) CContactItemField(aType);
       
   748 	CleanupStack::PushL(self);
       
   749 	self->ConstructStorageL();
       
   750 	self->iContentType=CContentType::NewL(aContentType);
       
   751 	return self;
       
   752 	}
       
   753  
       
   754 CContactItemField::CContactItemField(TStorageType aType)
       
   755 	: iStorageType(aType), iAttributes(ESynchronize|EOverRidesLabel|ELabelUnspecified),iTemplateFieldId(KNullFieldId)
       
   756     {}
       
   757 
       
   758 CContactItemField::CContactItemField()
       
   759 	: iAttributes(ESynchronize),iTemplateFieldId(KNullFieldId)
       
   760     {}
       
   761 
       
   762 void CContactItemField::ConstructStorageL()
       
   763     {
       
   764 	__ASSERT_DEBUG(iStorage==NULL,Panic(ECntPanicStorageAlreadyAllocated));
       
   765     switch (iStorageType)
       
   766         {
       
   767     case KStorageTypeText:
       
   768         iStorage=new(ELeave) CContactTextField;
       
   769         break;
       
   770     case KStorageTypeStore:
       
   771         iStorage=new(ELeave) CContactStoreField;
       
   772         break;
       
   773     case KStorageTypeDateTime:
       
   774         iStorage=new(ELeave) CContactDateField;
       
   775         break;
       
   776     case KStorageTypeContactItemId:
       
   777         iStorage=new(ELeave) CContactAgentField;
       
   778         break;
       
   779     default:
       
   780     	User::Leave(KErrNotSupported);
       
   781     	break;
       
   782         }
       
   783     }
       
   784 
       
   785 void CContactItemField::CloneL(const CContactItemField &aField)
       
   786 	{
       
   787 	iContentType=CContentType::NewL(aField.ContentType());
       
   788 	if (aField.iLabel)
       
   789 		iLabel=aField.iLabel->AllocL();
       
   790 	iAttributes=aField.iAttributes;
       
   791 	// copy extended attributes as well
       
   792 	iExtendedAttributes=aField.iExtendedAttributes; 
       
   793 	iTemplateFieldId=aField.iTemplateFieldId;
       
   794 	CopyStorageL(aField);
       
   795 	}
       
   796 
       
   797 void CContactItemField::CopyStorageL(const CContactItemField &aField)
       
   798 	{
       
   799 	switch(aField.StorageType())
       
   800 		{
       
   801 		case KStorageTypeText:
       
   802 			TextStorage()->SetTextL(aField.TextStorage()->Text());
       
   803 			break;
       
   804 		case KStorageTypeDateTime:
       
   805 			DateTimeStorage()->SetTime(aField.DateTimeStorage()->Time());
       
   806 			break;
       
   807 		case KStorageTypeContactItemId:
       
   808 			AgentStorage()->SetAgentId(aField.AgentStorage()->Value());
       
   809 			break;
       
   810 		case KStorageTypeStore:
       
   811 			if (aField.StoreStorage()->Thing())
       
   812 				{
       
   813 				StoreStorage()->SetThingL(*aField.StoreStorage()->Thing());
       
   814 				}
       
   815 			break;
       
   816 		}
       
   817 	}
       
   818 
       
   819 EXPORT_C CContactItemField::~CContactItemField()
       
   820 /** Frees all resources owned by the field (the label, the stored 
       
   821 data and the content type), prior to its destruction. */
       
   822     {
       
   823     delete iLabel;
       
   824     delete iStorage;
       
   825 	delete iContentType;
       
   826     }
       
   827 
       
   828 /**
       
   829 @internalTechnology
       
   830   */
       
   831 EXPORT_C void CContactItemField::Reset()
       
   832 	{
       
   833     delete iLabel;
       
   834 	iLabel=NULL;
       
   835     delete iStorage;
       
   836 	iStorage=NULL;
       
   837 	iContentType->Reset();
       
   838 	iStorageType=0;
       
   839 	iId=KNullFieldId	;
       
   840 	iAttributes=ESynchronize;
       
   841 	iExtendedAttributes=0;
       
   842 	iTemplateFieldId=KNullFieldId;
       
   843 	}
       
   844 
       
   845 void CContactItemField::MapHintsToFieldTypesL(THint aHint)
       
   846 	{
       
   847 	if (aHint.IsPhone())
       
   848 		AddFieldTypeL(KUidContactFieldPhoneNumber);
       
   849 	if (aHint.IsMsg())
       
   850 		AddFieldTypeL(KUidContactFieldMsg);
       
   851 	if (aHint.IsCompanyName())
       
   852 		AddFieldTypeL(KUidContactFieldCompanyName);
       
   853 	if (aHint.IsFamilyName())
       
   854 		AddFieldTypeL(KUidContactFieldFamilyName);
       
   855 	if (aHint.IsGivenName())
       
   856 		AddFieldTypeL(KUidContactFieldGivenName);
       
   857 	if (aHint.IsCompanyNamePronunciation())
       
   858 		AddFieldTypeL(KUidContactFieldCompanyNamePronunciation);
       
   859 	if (aHint.IsFamilyNamePronunciation())
       
   860 		AddFieldTypeL(KUidContactFieldFamilyNamePronunciation);
       
   861 	if (aHint.IsGivenNamePronunciation())
       
   862 		AddFieldTypeL(KUidContactFieldGivenNamePronunciation);
       
   863 	if (aHint.IsAddress())
       
   864 		AddFieldTypeL(KUidContactFieldAddress);
       
   865 	if (aHint.IsAdditionalName())
       
   866 		AddFieldTypeL(KUidContactFieldAdditionalName);
       
   867 	if (aHint.IsSuffixName())
       
   868 		AddFieldTypeL(KUidContactFieldSuffixName);
       
   869 	if (aHint.IsPrefixName())
       
   870 		AddFieldTypeL(KUidContactFieldPrefixName);
       
   871 	if (aHint.IsEmail())
       
   872 		AddFieldTypeL(KUidContactFieldEMail);
       
   873 	if (aHint.IsStorageInline())
       
   874 		AddFieldTypeL(KUidContactStorageInline);
       
   875 	}
       
   876 
       
   877 TBool CContactItemField::AddFieldToHint(TFieldType aFieldType, CContactItemField::THint &aHint) const 
       
   878   	{
       
   879 	TBool matchedHint = ETrue;
       
   880 	switch(aFieldType.iUid)
       
   881 		{
       
   882 		case KUidContactFieldAddressValue:
       
   883 			aHint.SetIsAddress();
       
   884 			break;
       
   885 		case KUidContactFieldCompanyNameValue:
       
   886 			aHint.SetIsCompanyName();
       
   887 			break;
       
   888 		case KUidContactFieldPhoneNumberValue:
       
   889 			aHint.SetIsPhone();
       
   890 			break;
       
   891 		case KUidContactFieldGivenNameValue:
       
   892 			aHint.SetIsGivenName();
       
   893 			break;
       
   894 		case KUidContactFieldFamilyNameValue:
       
   895 			aHint.SetIsFamilyName();
       
   896 			break;
       
   897 		case KUidContactFieldCompanyNamePronunciationValue:
       
   898 			aHint.SetIsCompanyNamePronunciation();
       
   899 			break;
       
   900 		case KUidContactFieldGivenNamePronunciationValue:
       
   901 			aHint.SetIsGivenNamePronunciation();
       
   902 			break;
       
   903 		case KUidContactFieldFamilyNamePronunciationValue:
       
   904 			aHint.SetIsFamilyNamePronunciation();
       
   905 			break;
       
   906 		case KUidContactFieldAdditionalNameValue:
       
   907 			aHint.SetIsAdditionalName();
       
   908 			break;
       
   909 		case KUidContactFieldSuffixNameValue:
       
   910 			aHint.SetIsSuffixName();
       
   911 			break;
       
   912 		case KUidContactFieldPrefixNameValue:
       
   913 			aHint.SetIsPrefixName();
       
   914 			break;
       
   915 		case KUidContactFieldEMailValue:
       
   916 			aHint.SetIsEmail();
       
   917 			break;
       
   918 		case KUidContactFieldMsgValue:
       
   919 			aHint.SetIsMsg();
       
   920 			break;
       
   921 		case KUidContactFieldStorageInlineValue:
       
   922 			aHint.SetStorageIsInline();
       
   923 			break;
       
   924 		default:
       
   925 			matchedHint=EFalse;
       
   926 			break;
       
   927 		}
       
   928 	return(matchedHint);
       
   929 	}
       
   930 
       
   931 
       
   932 /**
       
   933 Encode contact field data into stream store.
       
   934 
       
   935 @param aTextStream the text blob stream to export text data.
       
   936 @param aBlobStore the binary blob stream to export binary data.
       
   937 @param aTextFieldIndex the index of text field stored in the storage
       
   938 
       
   939 @return field header which is to be stored into header blob. 
       
   940 @internalTechnology 
       
   941 */
       
   942 TFieldHeader CContactItemField::StoreL(RWriteStream& aTextStream, CStreamStore& aBlobStore, TInt aTextFieldIndex)
       
   943 	{
       
   944 	TStreamId streamId = KNullStreamIdValue;
       
   945 	if (iStorageType == KStorageTypeText)
       
   946 		{
       
   947 		STATIC_CAST(CContactTextField*,iStorage)->ExternalizeL(aTextStream, ETrue, aTextFieldIndex);
       
   948 		}
       
   949 	else
       
   950 	    {
       
   951 		streamId = iStorage->StoreL(aBlobStore);
       
   952 	    }
       
   953 	
       
   954 	TContactFieldAtts atts;
       
   955 	/* sets all attributes of the field:- hidden private etc.. + type (text etc..)
       
   956 	   into TContactFieldAtts which is then stored ahead of the field data */
       
   957 	atts.SetAttribs(iAttributes);
       
   958 	atts.SetExtendedAttribs(iExtendedAttributes);
       
   959 	atts.SetType(iStorageType);
       
   960     return TFieldHeader(atts, iId, streamId);
       
   961 	}
       
   962 
       
   963 
       
   964 /**
       
   965 Decode given blob header stream into contact field relevent data.
       
   966 
       
   967 @param aStream reference to the blob header stream to be decoded.
       
   968 @param aSystemTemplateFields cached template fields.
       
   969 
       
   970 @return the stream id of content data stored in data store 
       
   971 @internalTechnology 
       
   972 */
       
   973 EXPORT_C TStreamId CContactItemField::RestoreFieldTypesL(RReadStream &aStream, const CContactItemFieldSet *aSystemTemplateFields)
       
   974   	{
       
   975 	THint hint;
       
   976 	TStreamId nestedId(KNullStreamIdValue);
       
   977 	TContactFieldAtts fieldAtts;
       
   978 
       
   979 	aStream >> fieldAtts;
       
   980 	
       
   981 	iAttributes = fieldAtts.Attribs();
       
   982 	iExtendedAttributes = fieldAtts.ExtendedAttribs();
       
   983 	iStorageType = fieldAtts.Type();
       
   984 	
       
   985     if(fieldAtts.Type() != KStorageTypeText)
       
   986         {
       
   987    	    //Only import stream id when the storage type is not text
       
   988         aStream >> nestedId;
       
   989         }
       
   990         
       
   991     iId = aStream.ReadUint32L();
       
   992     iTemplateFieldId = aStream.ReadUint32L();
       
   993     
       
   994 	const CContactItemField* templateField = NULL;
       
   995 	
       
   996 	if (UsesTemplateTypes() || !OverRidesLabel())
       
   997 		{
       
   998 		if (aSystemTemplateFields == NULL)
       
   999 		    {
       
  1000 			User::Leave(KErrCorrupt);
       
  1001 		    }
       
  1002 		templateField = aSystemTemplateFields->FindById(iTemplateFieldId);
       
  1003 		}
       
  1004 		
       
  1005 	if (templateField)
       
  1006 		{
       
  1007 		iAttributes |= (templateField->iAttributes&ETemplateMask);
       
  1008 		}
       
  1009 		
       
  1010 	if (UsesTemplateTypes() && templateField)
       
  1011 		{
       
  1012 		CContentType* newContent=CContentType::NewL(templateField->ContentType());
       
  1013 		delete iContentType;
       
  1014 		iContentType = NULL;
       
  1015 		iContentType=newContent;
       
  1016 		}
       
  1017 	else
       
  1018 		{
       
  1019   		hint = aStream.ReadInt32L();
       
  1020   		
       
  1021  		if(hint.HasVCardMappingUid())
       
  1022  		    {
       
  1023         	iContentType->SetMapping(TUid::Uid(aStream.ReadInt32L()));
       
  1024  		    }
       
  1025  		    
       
  1026 		MapHintsToFieldTypesL(hint);
       
  1027  		iContentType->InternalizeAdditionalUidsL(hint.AdditionalUidsNum(),aStream);
       
  1028 		}
       
  1029 		
       
  1030 	ConstructStorageL();
       
  1031 	
       
  1032 	if (OverRidesLabel())
       
  1033 		{
       
  1034 		const TInt length = aStream.ReadInt32L();
       
  1035 		if (length)
       
  1036 		    {
       
  1037 			iLabel = HBufC::NewL(aStream,length);
       
  1038 		    }
       
  1039 		}
       
  1040 	else if(templateField)
       
  1041 	    {
       
  1042 		iLabel = templateField->Label().AllocL();
       
  1043 	    }
       
  1044 		    
       
  1045 	return nestedId;
       
  1046     }
       
  1047 	
       
  1048 
       
  1049 void CContactItemField::RestoreDataL(CStreamStore& aStore,TStreamId aId)
       
  1050     {
       
  1051     RStoreReadStream stream;
       
  1052     stream.OpenLC(aStore,aId);
       
  1053 	iStorage->RestoreL(aStore,stream);
       
  1054 	CleanupStack::PopAndDestroy(); // stream
       
  1055 	}
       
  1056 
       
  1057 /**
       
  1058 @internalTechnology 
       
  1059 */
       
  1060 EXPORT_C void CContactItemField::RestoreTextL(HBufC *aTextStream,TInt aTextFieldIndex)
       
  1061     {
       
  1062 	__ASSERT_ALWAYS(iStorageType==KStorageTypeText,Panic(ECntPanicInvalidStorageType));
       
  1063     STATIC_CAST(CContactTextField*,iStorage)->InternalizeL(aTextStream,aTextFieldIndex);
       
  1064 	}
       
  1065 
       
  1066 /**
       
  1067 @internalTechnology 
       
  1068 */
       
  1069 EXPORT_C TBool CContactItemField::RestoreIfMatchL(RReadStream& aStream,const CContactItemFieldDef *aFieldDef, const CContactItemFieldSet *aSystemTemplateFields,HBufC *aTextStream,TInt aTextIndex)
       
  1070 	{
       
  1071 	TStreamId nestedId;
       
  1072 	nestedId=RestoreFieldTypesL(aStream,aSystemTemplateFields);
       
  1073 	TBool match=EFalse;
       
  1074 	if (aFieldDef==NULL)
       
  1075 		match=ETrue;
       
  1076 	else
       
  1077 		{
       
  1078 		for(TInt loop=0;loop<aFieldDef->Count();loop++)
       
  1079 			{
       
  1080 			TUid fieldType=(*aFieldDef)[loop];
       
  1081 			if (fieldType==KUidContactFieldMatchAll || iContentType->ContainsFieldType(fieldType))
       
  1082 				{
       
  1083 				match=ETrue;
       
  1084 				break;
       
  1085 				}
       
  1086 			}
       
  1087 		}
       
  1088 	if (match && iStorageType==KStorageTypeText)
       
  1089 		RestoreTextL(aTextStream,aTextIndex);
       
  1090 	return match;
       
  1091 	}
       
  1092 	        
       
  1093 TBool CContactItemField::RestoreIfMatchL(RReadStream& aRootStream,TFieldType aFieldType, const CContactItemFieldSet *aSystemTemplateFields,HBufC *aTextStream,TInt aTextIndex)
       
  1094 	{
       
  1095 	CContactItemFieldDef* fieldDef=new(ELeave) CContactItemFieldDef();
       
  1096 	CleanupStack::PushL(fieldDef);
       
  1097 	fieldDef->AppendL(aFieldType);
       
  1098 	TBool ret=RestoreIfMatchL(aRootStream,fieldDef, aSystemTemplateFields,aTextStream,aTextIndex);
       
  1099 	CleanupStack::PopAndDestroy();	// fieldDef
       
  1100 	return(ret);
       
  1101 	}
       
  1102 
       
  1103 EXPORT_C TStorageType CContactItemField::StorageType() const
       
  1104 /** Gets the field's storage type.
       
  1105 
       
  1106 @return The field's storage type. */
       
  1107     {
       
  1108     return iStorageType;
       
  1109     }
       
  1110 
       
  1111 EXPORT_C const CContentType &CContactItemField::ContentType() const
       
  1112 /** Gets the field's content type.
       
  1113 
       
  1114 @return Reference to the field's content type. */
       
  1115     {
       
  1116     return *iContentType;
       
  1117     }
       
  1118 
       
  1119 const CContentType &CContactItemField::TemplateContentType(const CContactItemFieldSet &aSystemTemplateFields) const
       
  1120 	{
       
  1121 	if (UsesTemplateTypes() || OverRidesLabel())
       
  1122 		return(*iContentType);
       
  1123 	const CContactItemField *templateField=aSystemTemplateFields.FindById(iTemplateFieldId);
       
  1124 	if (!templateField)
       
  1125 		return(*iContentType);
       
  1126 	return(templateField->ContentType());
       
  1127 	}
       
  1128 
       
  1129 EXPORT_C TPtrC CContactItemField::Label() const
       
  1130 /** Gets the field's label.
       
  1131 
       
  1132 @return The field label. If no label has been set, its length is zero. */
       
  1133     {
       
  1134     TPtrC label;
       
  1135     if (iLabel)
       
  1136         label.Set(*iLabel);
       
  1137     return label;
       
  1138     }
       
  1139 
       
  1140 EXPORT_C void CContactItemField::ResetStore()
       
  1141 /** Resets the field storage. The field's store is deleted, then re-allocated. */
       
  1142     {
       
  1143     delete iStorage;
       
  1144 	iStorage=NULL;
       
  1145 	ConstructStorageL();
       
  1146 	}
       
  1147 
       
  1148 EXPORT_C CContactFieldStorage *CContactItemField::Storage() const
       
  1149 /** Gets a pointer to the field's base storage.
       
  1150 
       
  1151 Rather than using this function and then casting to a specific storage class, 
       
  1152 one of the following functions should normally be used: TextStorage(), 
       
  1153 StoreStorage(), AgentStorage(), or DateTimeStorage().
       
  1154 
       
  1155 @return The field's base storage type. */
       
  1156     {
       
  1157     return iStorage;
       
  1158     }
       
  1159 
       
  1160 EXPORT_C CContactTextField *CContactItemField::TextStorage() const
       
  1161 /** Gets a pointer to the field's storage as a CContactTextField. 
       
  1162 
       
  1163 If the field's storage type is not KStorageTypeText, this function raises a panic.
       
  1164 
       
  1165 @return The field's storage as a CContactTextField*. */
       
  1166     {
       
  1167 	__ASSERT_ALWAYS(iStorageType==KStorageTypeText,Panic(ECntPanicInvalidStorageType));
       
  1168     return (CContactTextField *)iStorage;
       
  1169 	}
       
  1170 
       
  1171 EXPORT_C CContactStoreField *CContactItemField::StoreStorage() const
       
  1172 /** Gets a pointer to the field's storage as a CContactStoreField. 
       
  1173 
       
  1174 This indicates the field data is stored in a descriptor or descriptor array. 
       
  1175 If the field storage type is not KStorageTypeStore, this function raises a panic.
       
  1176 
       
  1177 @return Field's storage as a CContactStoreField*. */
       
  1178     {
       
  1179 	__ASSERT_ALWAYS(iStorageType==KStorageTypeStore,Panic(ECntPanicInvalidStorageType));
       
  1180     return (CContactStoreField *)iStorage;
       
  1181 	}
       
  1182 
       
  1183 EXPORT_C CContactAgentField *CContactItemField::AgentStorage() const
       
  1184 /** Gets a pointer to the field's storage as a CContactAgentField. 
       
  1185 
       
  1186 An agent is a property in a vCard which contains another person's contact details. 
       
  1187 If the field storage type is not KStorageTypeContactItemId, this function raises 
       
  1188 a panic.
       
  1189 
       
  1190 @return Field's storage as a CContactAgentField*. */
       
  1191     {
       
  1192 	__ASSERT_ALWAYS(iStorageType==KStorageTypeContactItemId,Panic(ECntPanicInvalidStorageType));
       
  1193     return (CContactAgentField *)iStorage;
       
  1194 	}
       
  1195 
       
  1196 EXPORT_C CContactDateField *CContactItemField::DateTimeStorage() const
       
  1197 /** Returns a pointer to the field's storage as a CContactDateField. 
       
  1198 
       
  1199 If the field storage type is not KStorageTypeDateTime, this function raises a panic.
       
  1200 
       
  1201 @return Field's storage as a CContactDateField*. */
       
  1202     {
       
  1203 	__ASSERT_ALWAYS(iStorageType==KStorageTypeDateTime,Panic(ECntPanicInvalidStorageType));
       
  1204     return (CContactDateField *)iStorage;
       
  1205 	}
       
  1206 
       
  1207 EXPORT_C void CContactItemField::AddFieldTypeL(TFieldType aFieldType)
       
  1208 /** Appends a field type to the field's content type.
       
  1209 
       
  1210 Note that certain combinations of field types are not valid and should not be
       
  1211 used.
       
  1212 
       
  1213 @param aFieldType The field type to append to the field's content type. */
       
  1214     {
       
  1215     iContentType->AddFieldTypeL(aFieldType);
       
  1216 	}
       
  1217 
       
  1218 EXPORT_C void CContactItemField::RemoveFieldType(TFieldType aFieldType)
       
  1219 /** Removes a field type from the field's content type.
       
  1220 
       
  1221 @param aFieldType The field type to remove from the field's content type. */
       
  1222 	{
       
  1223     iContentType->RemoveFieldType(aFieldType);
       
  1224 	}
       
  1225 
       
  1226 EXPORT_C void CContactItemField::SetMapping(TUid aMapping)
       
  1227 /** Sets the vCard mapping for the field's content type.
       
  1228 
       
  1229 @param aMapping The new mapping for the field's content type. */
       
  1230     {
       
  1231     iContentType->SetMapping(aMapping);
       
  1232     }
       
  1233 
       
  1234 EXPORT_C void CContactItemField::SetHidden(TBool aHidden)
       
  1235 /** Sets the value of the hidden attribute. 
       
  1236 
       
  1237 If hidden fields are included in the view definition, the field is displayed 
       
  1238 like other fields. If the view definition masks hidden fields, it is not displayed. 
       
  1239 See the TMode enumeration defined in class CContactItemViewDef.
       
  1240 
       
  1241 @param aHidden ETrue for hidden, EFalse for displayed. */
       
  1242     {
       
  1243     if (aHidden)
       
  1244         iAttributes|=EHidden;
       
  1245     else
       
  1246         iAttributes&=~EHidden;
       
  1247     }
       
  1248 
       
  1249 EXPORT_C void CContactItemField::SetReadOnly(TBool aReadOnly)
       
  1250 /** Sets the value of the field's read only attribute.
       
  1251 
       
  1252 @param aReadOnly ETrue to set the field's read only attribute, EFalse to unset 
       
  1253 the attribute. */
       
  1254     {
       
  1255     if (aReadOnly)
       
  1256         iAttributes|=EReadOnly;
       
  1257     else
       
  1258         iAttributes&=~EReadOnly;
       
  1259     }
       
  1260 
       
  1261 EXPORT_C void CContactItemField::SetSynchronize(TBool aSynchronize)
       
  1262 /** Sets the value of the field's synchronise attribute.
       
  1263 
       
  1264 @param aSynchronize ETrue to set synchronise attribute, EFalse to unset it. */
       
  1265     {
       
  1266     if (aSynchronize)
       
  1267         iAttributes|=ESynchronize;
       
  1268     else
       
  1269         iAttributes&=~ESynchronize;
       
  1270     }
       
  1271 
       
  1272 EXPORT_C void CContactItemField::SetDisabled(TBool aDisabled)
       
  1273 /** Sets the value of the disabled attribute.
       
  1274 
       
  1275 @param aDisabled ETrue to set the disabled attribute, EFalse to unset the 
       
  1276 attribute. */
       
  1277     {
       
  1278     if (aDisabled)
       
  1279         iAttributes|=EDisabled;
       
  1280     else
       
  1281         iAttributes&=~EDisabled;
       
  1282     }
       
  1283 
       
  1284 /** 
       
  1285 @internalComponent
       
  1286 */
       
  1287 void CContactItemField::UsesTemplateData(TInt aTemplateFieldId)
       
  1288 	{
       
  1289 	iTemplateFieldId=aTemplateFieldId;
       
  1290 	}
       
  1291 
       
  1292 void CContactItemField::SetLabelUnspecified(TBool aUnspecified)
       
  1293 	{
       
  1294 	if (aUnspecified)
       
  1295 		iAttributes|=ELabelUnspecified;
       
  1296 	else
       
  1297 		iAttributes&=~ELabelUnspecified;
       
  1298 	}
       
  1299 
       
  1300 EXPORT_C void CContactItemField::SetUserAddedField(TBool aUserAddedField)
       
  1301 /** Sets the user added field attribute.
       
  1302 
       
  1303 @param aUserAddedField ETrue to set the field's user added attribute, EFalse 
       
  1304 to unset it. */
       
  1305 	{
       
  1306 	if (aUserAddedField)
       
  1307 		iAttributes|=EUserAddedField;
       
  1308 	else
       
  1309 		iAttributes&=~EUserAddedField;
       
  1310 	}
       
  1311 
       
  1312 EXPORT_C void CContactItemField::SetTemplateField(TBool aTemplateField)
       
  1313 /** Sets whether the field is a template field.
       
  1314 
       
  1315 @param aTemplateField ETrue to set the field's Is template attribute. EFalse 
       
  1316 to unset it. */
       
  1317 	{
       
  1318 	if (aTemplateField)
       
  1319 		iAttributes|=ETemplate;
       
  1320 	else
       
  1321 		iAttributes&=~ETemplate;
       
  1322 	}
       
  1323 
       
  1324 EXPORT_C void CContactItemField::SetPrivate(TBool aPrivateField)
       
  1325 /** Sets the value of the field's private attribute. 
       
  1326 
       
  1327 This is used by the contact database when exporting a contact item as a vCard, 
       
  1328 to identify fields which should not be exported.
       
  1329 
       
  1330 @param aTemplateField ETrue to set the field's private attribute, EFalse to 
       
  1331 unset it. */
       
  1332 	{
       
  1333 	if (aPrivateField)
       
  1334 		iExtendedAttributes|=EPrivate;
       
  1335 	else
       
  1336 		iExtendedAttributes&=~EPrivate;
       
  1337 	}
       
  1338 
       
  1339 EXPORT_C void CContactItemField::SetSpeedDial(TBool aSpeedDialField)
       
  1340 /** Sets the value of the field's speed dial attribute.
       
  1341 
       
  1342 @param aSpeedDialField ETrue if the field should be a speed dial field, EFalse 
       
  1343 if not. */
       
  1344 	{
       
  1345 	if (aSpeedDialField)
       
  1346 		iExtendedAttributes|=ESpeedDial;
       
  1347 	else
       
  1348 		iExtendedAttributes&=~ESpeedDial;
       
  1349 	}
       
  1350 
       
  1351 /**
       
  1352 @internalTechnology 
       
  1353 */
       
  1354 EXPORT_C void CContactItemField::SetCustomFilterable(EContactFieldFlags aContactFilterType)
       
  1355 	{
       
  1356 	if (aContactFilterType == EContactFieldFlagFilterable) 
       
  1357 		{
       
  1358  		iExtendedAttributes |= EUserDefinedFilter;
       
  1359  		}
       
  1360   	else if (aContactFilterType == EContactFieldFlagFilterable1) 
       
  1361  		{
       
  1362  		iExtendedAttributes |= EUserDefinedFilter1;
       
  1363  		}
       
  1364  	else if (aContactFilterType == EContactFieldFlagFilterable2) 
       
  1365  		{
       
  1366  		iExtendedAttributes |= EUserDefinedFilter2;
       
  1367  		}
       
  1368  	else if (aContactFilterType == EContactFieldFlagFilterable3) 
       
  1369  		{
       
  1370  		iExtendedAttributes |= EUserDefinedFilter3;
       
  1371  		}
       
  1372  	else if (aContactFilterType == EContactFieldFlagFilterable4) 
       
  1373  		{
       
  1374  		iExtendedAttributes |= EUserDefinedFilter4;
       
  1375  		}
       
  1376 	}
       
  1377 
       
  1378 /** 
       
  1379 Determine if a custom filter exists. If it does, return the filter type.
       
  1380 
       
  1381 @param aContactFieldFlag The custom filter type if one exists.
       
  1382 @return ETrue if custom filter exists.
       
  1383 @internalTechnology 
       
  1384  */	
       
  1385 EXPORT_C TBool CContactItemField::HasCustomFilter(EContactFieldFlags& aContactFieldFlag) const
       
  1386 	{
       
  1387 	if (iExtendedAttributes & EUserDefinedFilter) 
       
  1388  		{
       
  1389  		aContactFieldFlag = EContactFieldFlagFilterable;
       
  1390  		return ETrue;
       
  1391  		}
       
  1392 	else if (iExtendedAttributes & EUserDefinedFilter1) 
       
  1393  		{
       
  1394  		aContactFieldFlag = EContactFieldFlagFilterable1;
       
  1395  		return ETrue;
       
  1396  		}
       
  1397  	else if (iExtendedAttributes & EUserDefinedFilter2) 
       
  1398  		{
       
  1399  		aContactFieldFlag = EContactFieldFlagFilterable2;
       
  1400  		return ETrue;
       
  1401  		}
       
  1402  	else if (iExtendedAttributes & EUserDefinedFilter3) 
       
  1403  		{
       
  1404  		aContactFieldFlag = EContactFieldFlagFilterable3;
       
  1405  		return ETrue;
       
  1406  		}
       
  1407  	else if (iExtendedAttributes & EUserDefinedFilter4) 
       
  1408  		{
       
  1409  		aContactFieldFlag = EContactFieldFlagFilterable4;
       
  1410  		return ETrue;
       
  1411  		}
       
  1412  		
       
  1413  	return EFalse;
       
  1414   	}
       
  1415   	
       
  1416 
       
  1417 void CContactItemField::UsesTemplateLabel()
       
  1418 	{
       
  1419 	iAttributes&=~EOverRidesLabel;
       
  1420 	SetLabelUnspecified(EFalse);
       
  1421 	}
       
  1422 
       
  1423 void CContactItemField::SetOverRidesLabel(TBool aValue)
       
  1424 	{
       
  1425 	if (aValue)
       
  1426 		{
       
  1427 		iAttributes|=EOverRidesLabel;
       
  1428 		}
       
  1429 	else
       
  1430 		{
       
  1431 		iAttributes&=~EOverRidesLabel;
       
  1432 		}
       
  1433 	}
       
  1434 
       
  1435 void CContactItemField::SetUsesTemplateTypes(TBool aUsesTemplateTypes)
       
  1436 	{
       
  1437 	if (aUsesTemplateTypes)
       
  1438 		iAttributes|=EUsesTemplateData;
       
  1439 	else
       
  1440 		iAttributes&=~EUsesTemplateData;
       
  1441 	}
       
  1442 
       
  1443 EXPORT_C void CContactItemField::SetLabelL(const TDesC& aLabel)
       
  1444 /** Sets the field label. 
       
  1445 
       
  1446 The label is allocated using TDesC::AllocL(), so the function can leave. 
       
  1447 Any existing label is replaced.
       
  1448 
       
  1449 @param aLabel The new field label. */
       
  1450     {
       
  1451 	SetLabel(aLabel.AllocL());
       
  1452     }
       
  1453 
       
  1454 EXPORT_C void CContactItemField::SetLabel(HBufC* aLabel)
       
  1455 /** Sets the field label. 
       
  1456 
       
  1457 The field takes ownership of aLabel so the function cannot leave.
       
  1458 
       
  1459 @param aLabel The new field label. */
       
  1460 	{
       
  1461 	delete iLabel;
       
  1462 	iLabel=aLabel;
       
  1463 	SetLabelUnspecified(EFalse);
       
  1464 	iAttributes|=EOverRidesLabel;
       
  1465 	}
       
  1466 
       
  1467 EXPORT_C void CContactItemField::SetId(TInt aId)
       
  1468 /** Sets the ID which uniquely identifies a field within a field set..
       
  1469 
       
  1470 Note that the field ID value is initialised when the field is added to the 
       
  1471 field set (using CContactItemFieldSet::AddL()). It is equivalent to the field's 
       
  1472 index within the field set array, and should not normally be changed.
       
  1473 
       
  1474 @param aId The new field ID. */
       
  1475 	{
       
  1476 	iId=aId;
       
  1477 	}
       
  1478 
       
  1479 EXPORT_C TInt CContactItemField::Id() const
       
  1480 /** Gets the field ID.
       
  1481 
       
  1482 @return The field ID. */
       
  1483 	{
       
  1484 	return(iId);
       
  1485 	}
       
  1486 
       
  1487 EXPORT_C TUint CContactItemField::UserFlags() const
       
  1488 /** Gets the value of the user flags, as set by SetUserFlags().
       
  1489 
       
  1490 @return The user flags value. */
       
  1491 	{
       
  1492 	return((iAttributes&EUserMask)>>EUserMaskShift);
       
  1493 	}
       
  1494 
       
  1495 EXPORT_C void CContactItemField::SetUserFlags(TUint aFlags)
       
  1496 /** Sets the value of the user flags.
       
  1497 
       
  1498 @param aFlags The user flags value. */
       
  1499 	{
       
  1500 	iAttributes&=~EUserMask;
       
  1501 	iAttributes|=((aFlags<<EUserMaskShift)&EUserMask);
       
  1502 	}
       
  1503 
       
  1504 TInt CContactItemField::TemplateFieldId() const
       
  1505 	{
       
  1506 	return iTemplateFieldId;
       
  1507 	}
       
  1508 
       
  1509 void CContactItemField::SetDeleted(TBool aDeleted)
       
  1510 	{
       
  1511 	if (aDeleted)
       
  1512 		iAttributes|=STATIC_CAST(TUint, EDeleted); 
       
  1513 	else
       
  1514 		iAttributes&=~EDeleted;
       
  1515 	}
       
  1516 
       
  1517 void CContactItemField::UpdateFieldFlags(const CContactItemFieldSet& aTemplateFieldSet)
       
  1518 	{
       
  1519 	TInt templatePosition;
       
  1520 	TBool exactMatch;
       
  1521 
       
  1522 	if (!Storage()->IsFull() && !IsTemplate())
       
  1523 		{
       
  1524 		SetDeleted(ETrue);
       
  1525 		}
       
  1526 	else
       
  1527 		{
       
  1528 		SetDeleted(EFalse);
       
  1529 		templatePosition = aTemplateFieldSet.MatchTemplateField(ContentType(),UserFlags(),exactMatch);
       
  1530 		if (templatePosition != KErrNotFound)
       
  1531 			{
       
  1532 			const CContactItemField& templateField = aTemplateFieldSet[templatePosition];
       
  1533 			UsesTemplateData(templateField.Id());
       
  1534 			SetUsesTemplateTypes(exactMatch);
       
  1535 			if (LabelUnspecified() || templateField.Label().CompareF(Label())==0)
       
  1536 				{
       
  1537 				UsesTemplateLabel();
       
  1538 				}
       
  1539 			}
       
  1540 		}
       
  1541 	SetLabelUnspecified(EFalse);
       
  1542 	}
       
  1543 
       
  1544 /** 
       
  1545 @internalTechnology 
       
  1546  */
       
  1547 EXPORT_C void CContactItemField::GetFieldText(TDes &aText) const 
       
  1548 	{
       
  1549 	if (StorageType()==KStorageTypeText)
       
  1550 		{
       
  1551 		TPtrC text=TextStorage()->Text();
       
  1552 		TInt length=text.Length();
       
  1553 		const TInt carriageReturn=13;
       
  1554 		const TInt lineFeed=10;
       
  1555 		for(TInt loop=0;loop<length;loop++)
       
  1556   			if ((TChar(text[loop])==carriageReturn) || (TChar(text[loop])==lineFeed))
       
  1557 				{
       
  1558 				length=loop;
       
  1559 				break;
       
  1560 				}
       
  1561 		if (length>KTextFieldMinimalLength)
       
  1562 			length=KTextFieldMinimalLength;
       
  1563 		aText.Copy(text.Left(length));
       
  1564 		}
       
  1565 	}
       
  1566 
       
  1567 EXPORT_C TBool CContactItemField::IsValidLabel(const TDesC& aLabel,TInt& aInvalidPos)
       
  1568 /** Tests whether a field label is valid.
       
  1569 
       
  1570 Note: the label is invalid if it contains any of the following characters: 
       
  1571 
       
  1572 [] (left or right square bracket) 
       
  1573 
       
  1574 = (equals sign)
       
  1575 
       
  1576 . (dot) 
       
  1577 
       
  1578 : (colon) 
       
  1579 
       
  1580 , (comma)
       
  1581 
       
  1582 @param aLabel The field label to test.
       
  1583 @param aInvalidPos On return, contains the character position within the label 
       
  1584 of the first invalid character. The first character position is zero.
       
  1585 @return ETrue if valid, EFalse if invalid. */
       
  1586 	{
       
  1587 		return !(((aInvalidPos = aLabel.Locate(KVersitTokenLSquareBracketVal)) != KErrNotFound) ||
       
  1588 		((aInvalidPos = aLabel.Locate(KVersitTokenRSquareBracketVal)) != KErrNotFound) ||
       
  1589 		((aInvalidPos = aLabel.Locate(KVersitTokenEqualsVal)) != KErrNotFound) ||
       
  1590 		((aInvalidPos = aLabel.Locate(KVersitTokenColonVal)) != KErrNotFound) ||
       
  1591 		((aInvalidPos = aLabel.Locate(KVersitTokenPeriodVal)) != KErrNotFound) ||
       
  1592 		((aInvalidPos = aLabel.Locate(KVersitTokenCommaVal)) != KErrNotFound));
       
  1593 	}
       
  1594 
       
  1595 EXPORT_C TBool CContactItemField::IsTemplateLabelField() const
       
  1596 /** Tests whether the field is a template label field (a field which holds 
       
  1597 the label for a contact card template: see class CContactCardTemplate).
       
  1598 
       
  1599 @return ETrue if the field is a template label field, EFalse if not. */
       
  1600 	{
       
  1601 	return (iContentType->ContainsFieldType(KUidContactFieldTemplateLabel));
       
  1602 	}
       
  1603 
       
  1604 
       
  1605 /** 
       
  1606 Part of the system template update implementation. 
       
  1607 This could be used for a generic update method at a later stage.
       
  1608 @internalTechnology
       
  1609 */
       
  1610 void CContactItemField::PopulateStoreL(RStoreWriteStream& aRootStream, TInt aCount, CArrayFix<TFieldHeader>& aFieldHeaderArray) const
       
  1611 	{
       
  1612 	if (!IsDeleted())
       
  1613 		{
       
  1614 		//Store attributes
       
  1615         aRootStream << aFieldHeaderArray[aCount].FieldAtts();
       
  1616         
       
  1617 		// since field is in fullFields it cannot be empty, so there is no need to check
       
  1618         if (StorageType() != KStorageTypeText)
       
  1619             {
       
  1620             aRootStream << aFieldHeaderArray[aCount].StreamId();
       
  1621             }
       
  1622 		
       
  1623 		//Store field id.
       
  1624 		aRootStream.WriteUint32L(iId);
       
  1625 		aRootStream.WriteUint32L(iTemplateFieldId);
       
  1626         
       
  1627 		CContactItemField::THint hint(0);
       
  1628         if(!UsesTemplateTypes())
       
  1629             {
       
  1630 			CArrayFixFlat<TUid>* additionalFields = new(ELeave) CArrayFixFlat<TUid>(5);
       
  1631 			CleanupStack::PushL(additionalFields);
       
  1632 			
       
  1633 			for(TInt loop=0; loop < iContentType->FieldTypeCount(); loop++)
       
  1634 				{
       
  1635 				TFieldType fieldType = iContentType->FieldType(loop);
       
  1636 				if (!AddFieldToHint(fieldType, hint))
       
  1637 				    {
       
  1638 					additionalFields->AppendL(fieldType);
       
  1639 				    }
       
  1640 				}
       
  1641 				
       
  1642 			const TInt KAdditionalUidsCount = additionalFields->Count();
       
  1643 			hint.SetAdditionalUidsNum(KAdditionalUidsCount);
       
  1644 			
       
  1645             if(iContentType->Mapping() != KNullUid)
       
  1646                 {
       
  1647                 //Store vCard mapping uid if there is a one.
       
  1648                 hint.SetHasVCardMappingUid();
       
  1649                 aRootStream.WriteInt32L(hint.iHintValue);
       
  1650     			aRootStream.WriteInt32L(iContentType->Mapping().iUid); // mapping
       
  1651                 }
       
  1652             else
       
  1653                 {
       
  1654                 aRootStream.WriteInt32L(hint.iHintValue);            
       
  1655                 }			
       
  1656 			
       
  1657 			for (TInt ii = 0; ii < KAdditionalUidsCount; ++ii) 
       
  1658 				{
       
  1659 				aRootStream.WriteInt32L((*additionalFields)[ii].iUid); // additional typing uids
       
  1660 				}
       
  1661 			CleanupStack::PopAndDestroy(); // additionalFields
       
  1662             }    
       
  1663 		
       
  1664 		if (OverRidesLabel())
       
  1665 			{ // store label if not inherited from template
       
  1666 			
       
  1667 			TInt length;
       
  1668 			
       
  1669 			if(iLabel)
       
  1670 				{
       
  1671 				length = iLabel->Length();
       
  1672 				}
       
  1673 			else
       
  1674 				{
       
  1675 				length = 0;
       
  1676 				}			
       
  1677 			
       
  1678 			aRootStream.WriteInt32L(length);	
       
  1679 				
       
  1680 			if (length > 0)
       
  1681 			    {
       
  1682 				aRootStream << *(iLabel);
       
  1683 			    }
       
  1684 			}
       
  1685 		} //if (!IsDeleted())
       
  1686 	}
       
  1687 
       
  1688 
       
  1689 /** 
       
  1690 Part of the system template update implementation. 
       
  1691 This could be used for a generic update method at a later stage.
       
  1692 @since 7.0
       
  1693 @internalTechnology
       
  1694 */
       
  1695 void CContactItemField::PrepareFieldAsTemplateL(CContactItemFieldSet& aSystemTemplateFieldSet)
       
  1696 	{
       
  1697 	TInt templatePosition = KErrNotFound;
       
  1698 	TBool exactMatch = EFalse;
       
  1699 	
       
  1700 	if ( !iStorage->IsFull() && !IsTemplate() )
       
  1701 		{
       
  1702 		SetDeleted(ETrue);
       
  1703 		} // if
       
  1704 	else
       
  1705 		{
       
  1706 		SetDeleted(EFalse);
       
  1707 		templatePosition = aSystemTemplateFieldSet.MatchTemplateField(ContentType(), UserFlags(), exactMatch);
       
  1708 		if (templatePosition != KErrNotFound)
       
  1709 			{
       
  1710 			const CContactItemField& systemTemplateField = aSystemTemplateFieldSet[templatePosition];
       
  1711 			UsesTemplateData( systemTemplateField.Id() );
       
  1712 			SetUsesTemplateTypes( exactMatch );
       
  1713 			if( LabelUnspecified() || systemTemplateField.Label().CompareF(Label()) == 0 )
       
  1714 				{
       
  1715 				UsesTemplateLabel();
       
  1716 				} 
       
  1717 			} //if
       
  1718 		} //else
       
  1719 
       
  1720 	SetLabelUnspecified(EFalse);
       
  1721 	}
       
  1722 
       
  1723 void CContactItemField::InternalizeL(RReadStream& aStream)
       
  1724 /** Internalises a CContactItemField object from a read stream. 
       
  1725 @param aStream Stream from which the object should be internalised. */
       
  1726 	{
       
  1727 
       
  1728 	delete iContentType;
       
  1729 	iContentType = NULL;
       
  1730 	iContentType = CContentType::NewL();
       
  1731 	iContentType->InternalizeL(aStream);
       
  1732 	
       
  1733 	iStorageType = aStream.ReadUint32L();
       
  1734 	
       
  1735 	if(iLabel)
       
  1736 		{
       
  1737 		delete iLabel;
       
  1738 		iLabel = NULL;
       
  1739 		}
       
  1740 	const TInt length=aStream.ReadInt32L();
       
  1741 	if (length)
       
  1742 		{
       
  1743 		iLabel=HBufC::NewL(aStream,length);	
       
  1744 		}
       
  1745 
       
  1746 	iId = aStream.ReadInt32L();
       
  1747 	
       
  1748 	iAttributes = aStream.ReadUint32L();
       
  1749 		
       
  1750 	iExtendedAttributes = aStream.ReadUint32L();
       
  1751 	
       
  1752 	delete iStorage;
       
  1753 	iStorage = NULL;
       
  1754 	ConstructStorageL();
       
  1755 	iStorage->InternalizeL(aStream);
       
  1756 	
       
  1757 	iTemplateFieldId = aStream.ReadInt32L();		
       
  1758 
       
  1759 	}
       
  1760 
       
  1761 void CContactItemField::ExternalizeL(RWriteStream& aStream) const 
       
  1762 /** Externalises a CContactItemField object to a write stream.
       
  1763 @param aStream Stream to which the object should be externalised. */
       
  1764 	{
       
  1765 	iContentType->ExternalizeL(aStream);
       
  1766 	
       
  1767 	aStream.WriteUint32L(iStorageType);
       
  1768 	
       
  1769 	if(iLabel)
       
  1770 		{
       
  1771 		
       
  1772 		const TInt length=iLabel->Length();
       
  1773 		aStream.WriteInt32L(length);	
       
  1774 		if (iLabel && length)
       
  1775 			{
       
  1776 			aStream<<*(iLabel);
       
  1777 			}
       
  1778 		}
       
  1779 		
       
  1780 	else
       
  1781 		{
       
  1782 		aStream.WriteInt32L(0);
       
  1783 		}
       
  1784 	
       
  1785 	aStream.WriteInt32L(iId);
       
  1786 	
       
  1787 	aStream.WriteUint32L(iAttributes);
       
  1788 		
       
  1789 	aStream.WriteUint32L(iExtendedAttributes);
       
  1790 	
       
  1791 	iStorage->ExternalizeL(aStream);
       
  1792 	
       
  1793 	aStream.WriteInt32L(iTemplateFieldId);
       
  1794 	}
       
  1795 
       
  1796 
       
  1797 
       
  1798 //
       
  1799 //	class THint
       
  1800 //
       
  1801 CContactItemField::THint::THint() : iHintValue(0)
       
  1802 	{}
       
  1803 
       
  1804 CContactItemField::THint::THint(TInt aValue)
       
  1805 	{
       
  1806 	iHintValue = aValue;
       
  1807 	}
       
  1808 
       
  1809 TBool CContactItemField::THint::operator==(const THint& aHint) const
       
  1810 	{
       
  1811 	return (iHintValue == aHint.iHintValue);
       
  1812 	}
       
  1813 
       
  1814 TBool CContactItemField::THint::operator!=(const THint& aHint) const	
       
  1815 	{
       
  1816 	return (iHintValue != aHint.iHintValue);
       
  1817 	}
       
  1818 
       
  1819 TInt  CContactItemField::THint::HintType() const
       
  1820 	{
       
  1821 	return (iHintValue & KHintTypeMask);
       
  1822 	}
       
  1823 
       
  1824 TInt CContactItemField::THint::TemplateFieldId() const
       
  1825     {
       
  1826     return (iHintValue & KHintTemplateFieldMask);    
       
  1827     }
       
  1828     
       
  1829 void  CContactItemField::THint::SetTemplateFieldId(TInt aTemplateFieldId)
       
  1830     {
       
  1831     iHintValue |= (aTemplateFieldId & KHintTemplateFieldMask);
       
  1832     }
       
  1833 
       
  1834 inline void CContactItemField::THint::SetHasVCardMappingUid()
       
  1835     {
       
  1836     iHintValue |= KHintVCardMappingMask;    
       
  1837     }
       
  1838     
       
  1839 inline TBool CContactItemField::THint::HasVCardMappingUid() const
       
  1840     {
       
  1841     return (iHintValue & KHintVCardMappingMask);    
       
  1842     }
       
  1843 
       
  1844 inline TInt CContactItemField::THint::AdditionalUidsNum() const
       
  1845     {
       
  1846     return ((iHintValue & KHintAdditionalMask) >> KHintAdditionalMaskShift);
       
  1847     }
       
  1848     
       
  1849 inline void CContactItemField::THint::SetAdditionalUidsNum(TInt aNumber)
       
  1850     {
       
  1851     iHintValue |= ((aNumber << KHintAdditionalMaskShift) & KHintAdditionalMask);       
       
  1852     }
       
  1853 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS	
       
  1854 inline void CContactItemField::THint::SetIsPhone()
       
  1855 	{iHintValue|=KIntContactHintIsPhone;}
       
  1856 inline void CContactItemField::THint::SetIsMsg()
       
  1857 	{iHintValue|=KIntContactHintIsMsg;}
       
  1858 // turn off Pronunciation bit too?
       
  1859 inline void CContactItemField::THint::SetIsCompanyName()
       
  1860 	{iHintValue|=KIntContactHintIsCompanyName;}
       
  1861 inline void CContactItemField::THint::SetIsFamilyName()
       
  1862 	{iHintValue|=KIntContactHintIsFamilyName;}
       
  1863 inline void CContactItemField::THint::SetIsGivenName()
       
  1864 	{iHintValue|=KIntContactHintIsGivenName;}
       
  1865 inline void CContactItemField::THint::SetIsCompanyNamePronunciation()
       
  1866 	{iHintValue|=KIntContactHintIsCompanyName|KIntContactHintIsPronunciation;}
       
  1867 inline void CContactItemField::THint::SetIsFamilyNamePronunciation()
       
  1868 	{iHintValue|=KIntContactHintIsFamilyName|KIntContactHintIsPronunciation;}
       
  1869 inline void CContactItemField::THint::SetIsGivenNamePronunciation()
       
  1870 	{iHintValue|=KIntContactHintIsGivenName|KIntContactHintIsPronunciation;}
       
  1871 inline void CContactItemField::THint::SetIsAddress()
       
  1872 	{iHintValue|=KIntContactHintIsAddress;}
       
  1873 inline void CContactItemField::THint::SetIsAdditionalName()
       
  1874 	{iHintValue|=KIntContactHintIsAdditionalName;}
       
  1875 inline void CContactItemField::THint::SetIsSuffixName()
       
  1876 	{iHintValue|=KIntContactHintIsSuffixName;}
       
  1877 inline void CContactItemField::THint::SetIsPrefixName()
       
  1878 	{iHintValue|=KIntContactHintIsPrefixName;}
       
  1879 inline void CContactItemField::THint::SetStorageIsInline()
       
  1880 	{iHintValue|=KIntContactHintStorageInline;}
       
  1881 inline void CContactItemField::THint::SetIsEmail()
       
  1882 	{iHintValue|=KIntContactHintIsEmail;}
       
  1883 inline TBool CContactItemField::THint::IsPhone() const
       
  1884 	{return (iHintValue&KIntContactHintIsPhone);}
       
  1885 inline TBool CContactItemField::THint::IsMsg() const
       
  1886 	{return (iHintValue&KIntContactHintIsMsg);}
       
  1887 inline TBool CContactItemField::THint::IsCompanyName() const
       
  1888 	{return ((iHintValue&KIntContactHintIsCompanyNamePronunciation) == KIntContactHintIsCompanyName);}
       
  1889 inline TBool CContactItemField::THint::IsFamilyName() const
       
  1890 	{return ((iHintValue&KIntContactHintIsFamilyNamePronunciation)==KIntContactHintIsFamilyName);}
       
  1891 inline TBool CContactItemField::THint::IsGivenName() const
       
  1892 	{return ((iHintValue&KIntContactHintIsGivenNamePronunciation)==KIntContactHintIsGivenName);}
       
  1893 inline TBool CContactItemField::THint::IsCompanyNamePronunciation() const
       
  1894 	{return ((iHintValue&KIntContactHintIsCompanyNamePronunciation) == KIntContactHintIsCompanyNamePronunciation);}
       
  1895 inline TBool CContactItemField::THint::IsFamilyNamePronunciation() const
       
  1896 	{return ((iHintValue&KIntContactHintIsFamilyNamePronunciation)==KIntContactHintIsFamilyNamePronunciation);}
       
  1897 inline TBool CContactItemField::THint::IsGivenNamePronunciation() const
       
  1898 	{return ((iHintValue&KIntContactHintIsGivenNamePronunciation)==KIntContactHintIsGivenNamePronunciation);}
       
  1899 inline TBool CContactItemField::THint::IsAddress() const
       
  1900 	{return (iHintValue&KIntContactHintIsAddress);}
       
  1901 inline TBool CContactItemField::THint::IsAdditionalName() const
       
  1902 	{return (iHintValue&KIntContactHintIsAdditionalName);}
       
  1903 inline TBool CContactItemField::THint::IsSuffixName() const
       
  1904 	{return (iHintValue&KIntContactHintIsSuffixName);}
       
  1905 inline TBool CContactItemField::THint::IsPrefixName() const
       
  1906 	{return (iHintValue&KIntContactHintIsPrefixName);}
       
  1907 inline TBool CContactItemField::THint::IsStorageInline() const
       
  1908 	{return (iHintValue&KIntContactHintStorageInline);}
       
  1909 inline TBool CContactItemField::THint::IsEmail() const
       
  1910 	{return (iHintValue&KIntContactHintIsEmail);}
       
  1911 	
       
  1912 #ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__	
       
  1913 inline void CContactItemField::THint::SetHasAdditionalUids()
       
  1914 	{iHintValue|=KHintAdditionalMask;}
       
  1915 #endif //__SYMBIAN_CNTMODEL_USE_SQLITE__ 
       
  1916 inline TBool CContactItemField::THint::Contains(const THint& aHint) const
       
  1917 	{return (iHintValue&aHint.iHintValue);}
       
  1918 #endif	
       
  1919 //
       
  1920 //	class TFieldHeader
       
  1921 //
       
  1922 
       
  1923 /*
       
  1924  * Default constructor
       
  1925  */
       
  1926 TFieldHeader::TFieldHeader()
       
  1927 : iFieldUid(0),
       
  1928   iStreamId(KNullStreamIdValue)
       
  1929     {
       
  1930     }
       
  1931 
       
  1932 /*
       
  1933  * Overloaded constructor
       
  1934  */
       
  1935 TFieldHeader::TFieldHeader(TContactFieldAtts aAtts, TUint32 aFieldUid, TStreamId aId)
       
  1936 : iAtts(aAtts),
       
  1937   iFieldUid(aFieldUid),
       
  1938   iStreamId(aId)
       
  1939     {
       
  1940     }
       
  1941     
       
  1942 inline TInt TFieldHeader::FieldId() const
       
  1943 	{
       
  1944 	return iFieldUid;
       
  1945 	}
       
  1946 
       
  1947 inline void TFieldHeader::SetFieldId(TInt aId) 
       
  1948 	{
       
  1949     iFieldUid = aId;
       
  1950 	}
       
  1951 
       
  1952 inline TContactFieldAtts TFieldHeader::FieldAtts() const
       
  1953     {
       
  1954     return iAtts;
       
  1955     }
       
  1956     
       
  1957 inline void TFieldHeader::SetFieldAtts(TContactFieldAtts aAtts)
       
  1958     {
       
  1959     iAtts = aAtts; 
       
  1960     }
       
  1961 
       
  1962 inline TStreamId TFieldHeader::StreamId() const
       
  1963     {
       
  1964     return iStreamId;    
       
  1965     }
       
  1966     
       
  1967 inline void TFieldHeader::SetStreamId(TStreamId aId)
       
  1968     {
       
  1969     iStreamId = aId;
       
  1970     }