diff -r 000000000000 -r e686773b3f54 pimprotocols/phonebooksync/Server/SyncContactICCEntry.cpp --- /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(KSyncArrayGranularity); + iGroupList = new (ELeave) CArrayFixFlat(KSyncArrayGranularity); + iEmailList = new (ELeave) CArrayFixFlat(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> addNumber; + iNumberList->AppendL(addNumber); + } + count = aStream.ReadInt32L(); // group list + for(i=0; i> group; + iGroupList->AppendL(group); + } + count = aStream.ReadInt32L(); // email list + for(i=0; i> email; + iEmailList->AppendL(email); + } + iSlotNum = aStream.ReadInt32L(); + iTON = static_cast(aStream.ReadUint32L()); + iContactId = aStream.ReadInt32L(); + iPhonebookUid = TUid::Uid(aStream.ReadInt32L()); + iIsHidden = static_cast(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; iAt(i); + count = iGroupList->Count(); // group list + aStream.WriteInt32L(count); + for(i=0; iAt(i); + count = iEmailList->Count(); // email list + aStream.WriteInt32L(count); + for(i=0; iAt(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(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 fieldIn8bit; + TBuf8 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(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()