pimprotocols/phonebooksync/Server/SyncContactICCEntry.cpp
changeset 0 e686773b3f54
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pimprotocols/phonebooksync/Server/SyncContactICCEntry.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,704 @@
+// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implementation of the Phonebook Synchroniser internal ICC Entry
+// representation class.
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "Phonebook.h"
+#include "PhonebookManager.h"
+#include "SyncContactICCEntry.h"
+#include "phbksync.h"
+#include "phbksyncsvr.h"
+#include "phbksyncsess.h"
+#include "phbksynclog.h"
+#include "common.h"
+
+
+/**
+ *  Granularity of the arrays.
+ */
+const TInt KSyncArrayGranularity = 4;
+
+
+/**
+ *  Utility function to panic the server if needed.
+ *
+ *  @param aPanicCode  Phonebook Synchroniser Fault type 
+ */
+GLDEF_C void PhBkSyncPanic(TPhBkSyncPanic aPanicCode)
+	{
+	LOGCOMMON2(_L8("PhBkSync Fault %d"), aPanicCode);
+	User::Panic(_L("PhBkSync Fault"), aPanicCode);
+	} // PhBkSyncPanic
+
+
+/**
+ *  Factory method to create a CSyncContactICCEntry object.
+ *
+ *  @return Pointer to a new CSyncContactICCEntry object.
+ */
+CSyncContactICCEntry* CSyncContactICCEntry::NewL()
+	{
+	CSyncContactICCEntry*  ptr = new (ELeave) CSyncContactICCEntry();
+	CleanupStack::PushL(ptr);
+	ptr->ConstructL();
+	CleanupStack::Pop(ptr);
+
+	return ptr;
+	} // CSyncContactICCEntry::NewL
+
+
+/**
+ *  Standard constructor.
+ */
+CSyncContactICCEntry::CSyncContactICCEntry()
+  : iSlotNum(0),
+    iTON(RMobilePhone::EUnknownNumber),
+    iContactId(KNullContactId),
+    iPhonebookUid(KUidIccGlobalAdnPhonebook),
+    iIsHidden(EFalse),
+    iTemplateId(KNullContactId)
+	{
+	// NOP
+	} // CSyncContactICCEntry::CSyncContactICCEntry
+
+
+/**
+ *  Second phase constructor.
+ */
+void CSyncContactICCEntry::ConstructL()
+	{
+	iNumberList = new (ELeave) CArrayFixFlat<TSyncAdditionalNumber>(KSyncArrayGranularity);
+	iGroupList = new (ELeave) CArrayFixFlat<TSyncEntryName>(KSyncArrayGranularity);
+	iEmailList = new (ELeave) CArrayFixFlat<TSyncEntryName>(KSyncArrayGranularity);
+	} //CSyncContactICCEntry::ConstructL
+
+
+/**
+ *  Standard destructor.
+ */
+CSyncContactICCEntry::~CSyncContactICCEntry()
+	{
+	delete iNumberList;
+	delete iGroupList;
+	delete iEmailList;
+	} // CSyncContactICCEntry::~CSyncContactICCEntry
+
+
+/**
+ *  This method stores the streamed contents of the object into a CBufBase
+ *  buffer.
+ *
+ *  @return Pointer to the allocated CBufFlat.
+ */
+CBufBase* CSyncContactICCEntry::StoreL()
+	{
+	CBufBase* buf=CBufFlat::NewL(KSyncArrayGranularity);
+	CleanupStack::PushL(buf);
+
+	RBufWriteStream  strm(*buf);
+	strm << *this;
+	strm.CommitL();
+	CleanupStack::Pop(buf);
+
+	return buf;
+	} // CSyncContactICCEntry::StoreL
+
+
+/**
+ *  This method stores the streamed contents of the oject into a
+ *  descriptor.
+ *
+ *  @param aDes  Descriptor in which to store the object.
+ */
+void CSyncContactICCEntry::StoreL(TDes8& aDes)
+	{
+	RDesWriteStream  strm(aDes);
+	strm << *this;
+	strm.CommitL();
+	} // CSyncContactICCEntry::StoreL
+
+
+/**
+ *  This method retrieves the contents of a CSyncContactICCEntry from a
+ *  descriptor.
+ *
+ * @param aBuf  Descriptor from which to read the CSyncContactICCEntry.
+ */
+void CSyncContactICCEntry::RestoreL(const TDesC8& aBuf)
+	{
+	RDesReadStream  strm(aBuf);
+	strm >> *this;
+	} // CSyncContactICCEntry::RestoreL
+
+
+/**
+ *  This method internalises the contents of a CSyncContactICCEntry from
+ *  a stream.
+ *
+ *  @param aStream  The read stream containing a CSyncContactICCEntry.
+ */
+void CSyncContactICCEntry::InternalizeL(RReadStream& aStream)
+	{
+	aStream >> iName;
+	aStream >> iSecondName;
+	aStream >> iNumber;
+	TInt count(aStream.ReadInt32L());	// list of additional numbers 
+	TInt i(0);
+	for(i=0; i<count; ++i)
+		{
+		TSyncAdditionalNumber addNumber;
+		aStream >> addNumber;
+		iNumberList->AppendL(addNumber);
+		}
+	count = aStream.ReadInt32L();		// group list
+	for(i=0; i<count; ++i)
+		{
+		TSyncEntryName group;
+		aStream >> group;
+		iGroupList->AppendL(group);
+		}
+	count = aStream.ReadInt32L();		// email list
+	for(i=0; i<count; ++i)
+		{
+		TSyncEntryName email;
+		aStream >> email;
+		iEmailList->AppendL(email);
+		}
+	iSlotNum = aStream.ReadInt32L();
+	iTON = static_cast<RMobilePhone::TMobileTON>(aStream.ReadUint32L());
+	iContactId = aStream.ReadInt32L();
+	iPhonebookUid = TUid::Uid(aStream.ReadInt32L());
+	iIsHidden = static_cast<TBool>(aStream.ReadInt32L());
+	iTemplateId = aStream.ReadInt32L();
+	} // CSyncContactICCEntry::InternalizeL
+
+
+/**
+ *  This method externalizes the contents of a CSyncContactICCEntry into
+ *  a stream.
+ *
+ *  @param aStream  The write stream that will contain a CSyncContactICCEntry.
+ */
+void CSyncContactICCEntry::ExternalizeL(RWriteStream& aStream) const
+	{
+	aStream << iName;
+	aStream << iSecondName;
+	aStream << iNumber;
+	TInt count(iNumberList->Count());	// list of additional numbers
+	TInt i(0);
+	aStream.WriteInt32L(count);
+	for(i=0; i<count; ++i)
+		aStream << iNumberList->At(i);
+	count = iGroupList->Count();		// group list
+	aStream.WriteInt32L(count);
+	for(i=0; i<count; ++i)
+		aStream << iGroupList->At(i);
+	count = iEmailList->Count();		// email list
+	aStream.WriteInt32L(count);
+	for(i=0; i<count; ++i)
+		aStream << iEmailList->At(i);
+	aStream.WriteInt32L(iSlotNum); 
+	aStream.WriteUint32L(iTON);
+	aStream.WriteInt32L(iContactId);
+	aStream.WriteInt32L(iPhonebookUid.iUid);
+	aStream.WriteInt32L(iIsHidden);
+	aStream.WriteInt32L(iTemplateId);
+	} // CSyncContactICCEntry::ExternalizeL
+
+
+/**
+ *  Initialise the class members from data taken from a CContactICCEntry.
+ *
+ *  @param aContactItem  Contacts ICC entry 
+ *
+ *  @return TInt KErrNotSupported if a non-supported field supplied in field set, KErrOverflow for an overflow, 
+ *          othewise KErrNone
+ */
+void CSyncContactICCEntry::InitialiseFromContactICCEntryL(const CContactICCEntry& aContactItem)
+	{
+	//
+	// Clear the fields to start with...
+	//
+	Reset();
+
+	TInt retrievedFields(0); // Number of fields retrieved from aContactItem field set 
+	iContactId = aContactItem.Id(); // get Contact UID
+	CContactItemFieldSet& fieldSet = aContactItem.CardFields();
+
+	TInt index(0), firstPhoneNumIndex(0);
+	// get default phone number field from aContacItem
+	firstPhoneNumIndex = fieldSet.Find(KUidContactFieldPhoneNumber);
+	if(firstPhoneNumIndex != KErrNotFound)
+		{
+		++retrievedFields;
+		const CContactItemField& field = fieldSet[firstPhoneNumIndex];
+		if(field.TextStorage()->Text().Length() > RMobilePhone::KMaxMobileTelNumberSize)
+			{
+			User::Leave(KErrOverflow);
+			}
+
+		TPtrC number(field.TextStorage()->Text());
+		iNumber.Copy(number);
+
+		//
+		// Set the TON/NPI for that number as International if the number contains
+		// the '+' prefix, otherwise set it to unknown.
+		//
+		if (TLex(iNumber).Get() == '+')
+			{
+			iTON = RMobilePhone::EInternationalNumber;
+			}
+		else
+			{
+			iTON = RMobilePhone::EUnknownNumber;
+			}
+
+		// Check whether this entry is hidden 
+		if(const_cast<CContactICCEntry&>(aContactItem).IsHidden())
+			iIsHidden = ETrue;
+
+		// Retrieve family name
+		if((index = fieldSet.Find(KUidContactFieldFamilyName)) != KErrNotFound)
+			{
+			++retrievedFields;
+			// get given name field from aContactItem
+			if(field.TextStorage()->Text().Length() > CSyncContactICCEntry::KMaxPhBkNameSize)
+				{
+				User::Leave(KErrOverflow);
+				}
+			iName.Copy(fieldSet[index].TextStorage()->Text());
+			} // name is not a compulsory field, so do not return an error if not found
+
+		// retrieve second name
+		if((index = fieldSet.Find(KUidContactFieldSecondName)) != KErrNotFound)
+			{
+			++retrievedFields;
+			// get given name field from aContactItem
+			if(field.TextStorage()->Text().Length() > CSyncContactICCEntry::KMaxPhBkNameSize)
+				{
+				User::Leave(KErrOverflow);
+				}
+			iSecondName.Copy(fieldSet[index].TextStorage()->Text());
+			} // name is not a compulsory field, so do not return an error if not found
+
+		// get slot number field from aContactItem
+		index = fieldSet.Find(KUidContactFieldICCSlot);
+		if(index!=KErrNotFound) // index field provided
+			{
+			++retrievedFields;
+			TPtrC tempPtr(NULL,0);
+			tempPtr.Set(fieldSet[index].TextStorage()->Text());
+			TLex lex(tempPtr);
+			TInt slot;
+			TInt ret(lex.Val(slot));
+			if (ret == KErrNone) // index field value supplied 
+				{
+				iSlotNum = slot;
+				}
+			else
+				iSlotNum = KSyncIndexNotSupplied; // index field provided as template field, so no actual values supplied
+			}
+		else
+			{
+			// all fields supplied but slot field not found so it must be a new entry
+			iSlotNum = KSyncIndexNotSupplied; // Set index to KSyncIndexNotSupplied
+			}
+
+		// handle the a phonebook UID field if present (it should always be as it is in the template)...
+		index = fieldSet.Find(KUidContactFieldICCPhonebook);
+		if(index!=KErrNotFound) // index field provided
+			{
+			++retrievedFields;
+			TPtrC tempPtr(NULL,0);
+			tempPtr.Set(fieldSet[index].TextStorage()->Text());
+			TLex lex(tempPtr);
+			TInt phonebook;
+			TInt ret(lex.Val(phonebook));
+			if (ret == KErrNone) // index field value supplied 
+				{
+				iPhonebookUid.iUid = phonebook;
+				}
+			else
+				{
+				iPhonebookUid = KUidIccGlobalAdnPhonebook;
+				}
+			}
+		else
+			{
+			iPhonebookUid = KUidIccGlobalAdnPhonebook;
+			}
+
+		// now get list of additional phone numbers from CContactICCEntry 		
+		index = firstPhoneNumIndex;  // skip the default phone number which has been read in early
+		while((index = fieldSet.FindNext(KUidContactFieldPhoneNumber,index+1)) != KErrNotFound)
+			{
+			// get additional phone number field from aContacItem
+			++retrievedFields;
+			const CContactItemField& field = fieldSet[index];
+			if(field.TextStorage()->Text().Length() > RMobilePhone::KMaxMobileTelNumberSize)
+				{
+				User::Leave(KErrOverflow);
+				}
+
+			TPtrC number(field.TextStorage()->Text());
+			CSyncContactICCEntry::TSyncAdditionalNumber addNumber;
+			addNumber.iNumber.Copy(number);
+
+			//
+			// Set the TON/NPI for that number as International if the number contains
+			// the '+' prefix, otherwise set it to unknown.
+			//
+			if (TLex(addNumber.iNumber).Get() == '+')
+				{
+				addNumber.iTON = RMobilePhone::EInternationalNumber;
+				}
+			else
+				{
+				addNumber.iTON = RMobilePhone::EUnknownNumber;
+				}
+
+            //-- assign alpha string to the additional number according to additional field types
+			const CContentType&  cntType = field.ContentType();
+		    
+		    //
+		    // Assume HOME by default. Please note that this will be used as default 
+		    // value if something other than HOME or WORK is supplied.
+		    //
+			if (cntType.ContainsFieldType(KUidContactFieldVCardMapWORK)) 
+				{
+				addNumber.iNumberString.Append(KVersitParamWork);
+				}
+			else
+				{
+				addNumber.iNumberString.Append(KVersitParamHome);
+				}
+
+		    //
+		    // Try to locate other tags (FAX, CELL, etc)...
+			//
+			if (cntType.ContainsFieldType(KUidContactFieldVCardMapMSG))
+				{
+				addNumber.iNumberString.Append(KVersitParamMsg);
+				}
+			else if (cntType.ContainsFieldType(KUidContactFieldVCardMapVOICE))
+				{
+				addNumber.iNumberString.Append(KVersitParamVoice);
+				}
+			else if (cntType.ContainsFieldType(KUidContactFieldVCardMapFAX))
+				{
+				addNumber.iNumberString.Append(KVersitParamFax);
+				}
+			else if (cntType.ContainsFieldType(KUidContactFieldVCardMapPREF))
+				{
+				addNumber.iNumberString.Append(KVersitParamPref);
+				}
+			else if (cntType.ContainsFieldType(KUidContactFieldVCardMapCELL))
+				{
+				addNumber.iNumberString.Append(KVersitParamCell);
+				}
+			else if (cntType.ContainsFieldType(KUidContactFieldVCardMapPAGER))
+				{
+				addNumber.iNumberString.Append(KVersitParamPager);
+				}
+			else if (cntType.ContainsFieldType(KUidContactFieldVCardMapBBS))
+				{
+				addNumber.iNumberString.Append(KVersitParamBbs);
+				}
+			else if (cntType.ContainsFieldType(KUidContactFieldVCardMapMODEM))
+				{
+				addNumber.iNumberString.Append(KVersitParamModem);
+				}
+			else if (cntType.ContainsFieldType(KUidContactFieldVCardMapCAR))
+				{
+				addNumber.iNumberString.Append(KVersitParamCar);
+				}
+			else if (cntType.ContainsFieldType(KUidContactFieldVCardMapISDN))
+				{
+				addNumber.iNumberString.Append(KVersitParamIsdn);
+				}
+			else if (cntType.ContainsFieldType(KUidContactFieldVCardMapVIDEO))
+				{
+				addNumber.iNumberString.Append(KVersitParamVideo);
+				}
+
+			// finally append additional number to additional number list
+			iNumberList->AppendL(addNumber);
+			}
+
+		// get all e-mail fields 
+		index = -1;
+		while((index = fieldSet.FindNext(KUidContactFieldEMail,index+1)) != KErrNotFound)
+			{
+			++retrievedFields;
+			// get e-mail field from aContactItem
+			if(field.TextStorage()->Text().Length() > CSyncContactICCEntry::KMaxPhBkNameSize)
+				{
+				User::Leave(KErrOverflow);
+				}
+
+			CSyncContactICCEntry::TSyncEntryName name;
+			name.Copy(fieldSet[index].TextStorage()->Text());
+			iEmailList->AppendL(name);
+			} // e-mail is not a compulsory field, so do not return an error if not found
+
+		// get all groups that this entry belongs to 
+		index = -1; // following was originally commented out (JJ)	
+		while((index = fieldSet.FindNext(KUidContactFieldICCGroup, index+1)) != KErrNotFound)
+			{
+			++retrievedFields;
+			// get group field from aContactItem
+			if(field.TextStorage()->Text().Length() > CSyncContactICCEntry::KMaxPhBkNameSize)
+				{
+				User::Leave(KErrOverflow);
+				}
+
+			CSyncContactICCEntry::TSyncEntryName name;
+			name.Copy(fieldSet[index].TextStorage()->Text());
+			iGroupList->AppendL(name);
+			} // group is not a compulsory field, so do not return an error if not foun
+
+		// For new entries phonebook type is not supplied, so always extract Template ID
+		iTemplateId = aContactItem.TemplateRefId();
+		}			
+
+	//
+	// Check that all expected fields were retrieved...
+	//
+	if (fieldSet.Count() != retrievedFields)
+		{
+#ifdef _DEBUG
+		//
+		// At least one field has was not supported. Log all the field types!
+		//
+		LOGCOMMON1(_L8("CSyncContactICCEntry: Unsupported field found!"));
+		for (TInt field = 0;  field < fieldSet.Count();  field++)
+			{
+			LOGCOMMON2(_L8("CSyncContactICCEntry:   Field[%d]:"), field);
+			for (TInt type = 0;  type < fieldSet[field].ContentType().FieldTypeCount();  type++)
+				{
+				LOGCOMMON3(_L8("CSyncContactICCEntry:     Type[%d]=0x%08x"), type,
+				           fieldSet[field].ContentType().FieldType(type));
+				}
+			}
+#endif
+
+		User::Leave(KErrNotSupported);
+		}
+	} // CSyncContactICCEntry::InitialiseFromContactICCEntryL
+
+
+
+
+/**
+ *  This method resets all attributes.
+ */
+void CSyncContactICCEntry::Reset()
+	{
+	// reset all variables
+	iSlotNum      = 0; 
+	iTON          = RMobilePhone::EUnknownNumber;
+	iContactId    = KNullContactId;
+	iPhonebookUid = KUidIccGlobalAdnPhonebook; 
+	iIsHidden     = EFalse; 
+	iTemplateId   = KNullContactId;
+	iName.Zero();
+	iSecondName.Zero();
+	iNumber.Zero();
+
+	// reset all lists
+	iNumberList->Reset();
+	iGroupList->Reset();	
+	iEmailList->Reset();
+	} // CSyncContactICCEntry::Reset
+
+
+#ifdef _DEBUG
+/**
+ *  Logs the contact entry for debugging purposes.
+ */
+void CSyncContactICCEntry::LogSyncContactICCEntry() const
+	{
+	//
+	// Log the basic fields...
+	//
+	TBuf8<KMaxPhBkNameSize>  fieldIn8bit;
+	TBuf8<RMobilePhone::KMaxMobileTelNumberSize>  numberIn8bit;
+
+	fieldIn8bit.Copy(iName);
+	LOGCOMMON2(_L8("ICCEntry: Name=\"%S\""), &fieldIn8bit);
+
+	fieldIn8bit.Copy(iSecondName);
+	LOGCOMMON2(_L8("ICCEntry: Second Name=\"%S\""), &fieldIn8bit);
+
+	numberIn8bit.Copy(iNumber);
+	LOGCOMMON2(_L8("ICCEntry: Number=\"%S\""), &numberIn8bit);
+
+	LOGCOMMON2(_L8("ICCEntry: SlotNum=%d"), iSlotNum);
+
+	LOGCOMMON2(_L8("ICCEntry: TypeOfNum=%d"), iTON);
+
+	LOGCOMMON2(_L8("ICCEntry: ContactID=0x%08x"), iContactId);
+
+	LOGCOMMON2(_L8("ICCEntry: PhonebookUID=0x%08x"), iPhonebookUid.iUid);
+
+	LOGCOMMON2(_L8("ICCEntry: IsHidden=%d"), iIsHidden);
+
+	LOGCOMMON2(_L8("ICCEntry: TemplateId=%d"), iTemplateId);
+
+	//
+	// Log the number list...
+	//
+	TInt  listCount(iNumberList->Count());
+	TInt  index;
+
+	for (index = 0;  index < listCount;  index++)
+		{
+		numberIn8bit.Copy(iNumberList->At(index).iNumber);
+		fieldIn8bit.Copy(iNumberList->At(index).iNumberString);
+		LOGCOMMON4(_L8("ICCEntry: NumberList[%d] \"%S\" \"%S\""),
+				   index, &numberIn8bit, &fieldIn8bit);
+		}
+
+	//
+	// Log the group list...
+	//
+	listCount = iGroupList->Count();
+
+	for (index = 0;  index < listCount;  index++)
+		{
+		fieldIn8bit.Copy(iGroupList->At(index));
+		LOGCOMMON3(_L8("ICCEntry: GroupList[%d]=\"%S\""), index, &fieldIn8bit);
+		}
+
+	//
+	// Log the email list...
+	//
+	listCount = iEmailList->Count();
+
+	for (index = 0;  index < listCount;  index++)
+		{
+		fieldIn8bit.Copy(iEmailList->At(index));
+		LOGCOMMON3(_L8("ICCEntry: EmailList[%d]=\"%S\""), index, &fieldIn8bit);
+		}
+	} // CSyncContactICCEntry::LogSyncContactICCEntry
+#endif
+
+
+/**
+ *  This method internalizes the contents of TSyncAdditionalNumber from
+ *  a stream.
+ *
+ *  @param aStream  The read stream containing TSyncAdditionalNumber.
+ */
+void CSyncContactICCEntry::TSyncAdditionalNumber::InternalizeL(RReadStream& aStream)
+	{
+	aStream >> iNumber;
+	aStream >> iNumberString;
+	iTON = static_cast<RMobilePhone::TMobileTON>(aStream.ReadUint32L());
+	} // CSyncContactICCEntry::TSyncAdditionalNumber::InternalizeL
+
+
+/**
+ *  This method externalizes the contents of TSyncAdditionalNumber into
+ *  a stream.
+ *
+ *  @param aStream  The write stream that will contain TSyncAdditionalNumber.
+ */
+void CSyncContactICCEntry::TSyncAdditionalNumber::ExternalizeL(RWriteStream& aStream) const
+	{
+	aStream << iNumber;
+	aStream << iNumberString;
+	aStream.WriteUint32L(iTON);
+	} // CSyncContactICCEntry::TSyncAdditionalNumber::ExternalizeL
+
+
+/**
+ *  Standard constructor.
+ */
+TContactFieldFormat::TContactFieldFormat(TInt aLength, TInt aCount,
+										 TBool aDisplayed)
+  : iLength(aLength),
+    iCount(aCount),
+    iDisplayed(aDisplayed)
+	{
+	// NOP
+	} // TContactFieldFormat::TContactFieldFormat
+
+
+/**
+ *  The old PhBkSyncServerThread Server Thread. This thread is no longer
+ *  supported.
+ */
+EXPORT_C TInt PhBkSyncServerThread(TAny*)
+	{
+	return KErrNotSupported;
+	} // PhBkSyncServerThread
+
+
+/**
+ *  This method returns the Phonebook Synchroniser API extension number
+ *  of the class.
+ *
+ *  @return An integer that will indicate the version of the type.
+ */
+EXPORT_C TInt RPhoneBookSession::TContactFieldsV1::ExtensionId() const
+	{
+	return iExtensionId;
+	} // RPhoneBookSession::TContactFieldsV1::ExtensionId()
+
+
+/**
+ *  Standard constructor.
+ */
+EXPORT_C RPhoneBookSession::TContactFieldsV1::TContactFieldsV1()
+  : iNameField(0, 0, EFalse),
+    iNumberField(0,0,EFalse),
+    iIccSlotField(0,0,EFalse), 
+    iExtensionId(KPhBkSyncTContactFieldsV1)
+	{
+	// NOP
+	} // RPhoneBookSession::TContactFieldsV1::TContactFieldsV1
+
+
+/**
+ *  Standard constructor.
+ */
+EXPORT_C RPhoneBookSession::TContactFieldsV2::TContactFieldsV2()
+  : TContactFieldsV1(),
+    iAdditionalNumString(0, 0, EFalse),
+    iGroupField(0,0,EFalse), 
+    iEmailField(0,0,EFalse),
+    iPhonebook(KUidIccGlobalAdnPhonebook)
+	{
+	iExtensionId = KPhBkSyncTContactFieldsV2;
+	} // RPhoneBookSession::TContactFieldsV2::TContactFieldsV2()
+
+
+/**
+ *  Standard constructor.
+ */
+EXPORT_C RPhoneBookSession::TContactFieldsV3::TContactFieldsV3()
+  : TContactFieldsV2(),
+    iAdditionalNumAlphaString(0, 0, EFalse),
+    iSecondNameField(0,0,EFalse)
+	{
+	iExtensionId = KPhBkSyncTContactFieldsV3;
+	} // RPhoneBookSession::TContactFieldsV3::TContactFieldsV3()