diff -r 000000000000 -r e686773b3f54 phonebookengines/VirtualPhonebook/VPbkSimStoreImpl/src/CVPbkSimCntField.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/VirtualPhonebook/VPbkSimStoreImpl/src/CVPbkSimCntField.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,318 @@ +/* +* Copyright (c) 2002-2007 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: The sim contact field. +* +*/ + + + +// INCLUDE FILES +#include "CVPbkSimCntField.h" + +#include "MVPbkSimCntStore.h" +#include "MVPbkSimContact.h" +#include "VPbkSimStoreTemplateFunctions.h" +#include "TVPbkSimStoreProperty.h" + +// ============================ LOCAL FUNCTIONS ================================ + +namespace { + +// CONSTANTS + +// a plus character the can be used as a prefix number +_LIT( KPlusPrefix, "+" ); + +// If there is no extension file or it's full then the number +// length is max 20. This comes from 3GPP USIM specification. +// (See spec for e.g EF ADN, 10 bytes for number) +const TInt KMaxNumLengthNotUsingExt = 20; +// If the number uses one record in the extension the max length is 40 +// This comes from 3GPP USIM specification. See e.g EF EXT1, one record +// can take 10 bytes number -> if number is splitted to EF ADN + one record +// in EF EXT1 then max length is 40 +const TInt KMaxNumLengthOneRecordFromExt = 40; + + +// ----------------------------------------------------------------------------- +// MaxLength +// +// Returns the maximum length of the new field that has the given type +// ----------------------------------------------------------------------------- +// +TInt16 MaxLength( TVPbkSimCntFieldType aType, const MVPbkSimCntStore& aStore ) + { + TInt result = 0; + if ( aType == EVPbkSimName || + aType == EVPbkSimGsmNumber ) + { + TVPbkGsmStoreProperty prop; + TInt err = aStore.GetGsmStoreProperties( prop ); + if( err != KErrNone ) + { + result = 0; + } + else if( aType == EVPbkSimName ) + { + result = prop.iMaxTextLength; + } + else + { + result = prop.iMaxNumLength; + } + } + else + { + TVPbkUSimStoreProperty uprop; + TInt err = aStore.GetUSimStoreProperties( uprop ); + if( err == KErrNone ) + { + switch ( aType ) + { + case EVPbkSimAdditionalNumber: + { + result = uprop.iMaxAnrLength; + break; + } + case EVPbkSimReading: + case EVPbkSimNickName: + { + result = uprop.iMaxScndNameLength; + break; + } + case EVPbkSimEMailAddress: + { + result = uprop.iMaxEmailLength; + break; + } + case EVPbkSimGroupName: + { + result = uprop.iMaxGroupNameLength; + break; + } + default: + { + break; + } + } + } + } + return (TInt16)result; + } + +// ----------------------------------------------------------------------------- +// CalculateNumberMaxLength +// +// Calculates the maximum number length for existing SIM contact. +// +// The logic is based on the file structure in SIM card. +// E.g a record in EF ADN can hold a phonenumber of length 20. If the saved +// number is longer than 20 the rest of the number is saved to EF EXT1. +// The size of EF EXT1 is limited and it doesn't have a space for each +// record in EF ADN. +// +// When getting maximum length from ETel it gives the max length that could +// be used for a new contact. But it's not the same as the max length that +// can be used for existing contact. +// +// This function checks how full the EXT1 file is using the contacts current +// number length and the max length from ETel. +// +// @param aInitialData the data that is saved in the SIM card +// @param aCurETelMaxLengthWithPlusPrefix a max number length from ETel with +// '+' prefix. +// @param aSystemMaxLength the system maximum length defined in VPbk. +// ----------------------------------------------------------------------------- +// +TInt16 CalculateNumberMaxLength( const TDesC& aInitialData, TInt + aCurETelMaxLengthWithPlusPrefix, + TInt aSystemMaxLength ) + { + TInt curLength = aInitialData.Length(); + if ( aInitialData.Find( KPlusPrefix ) != KErrNotFound ) + { + // Number contains '+' -prefix. Take that away to get + // the actual number length + --curLength; + } + + // Lets do the checkings without plus prefix + TInt curETelMaxLength = aCurETelMaxLengthWithPlusPrefix - 1; + + TInt result = curETelMaxLength; + if ( curETelMaxLength > KMaxNumLengthOneRecordFromExt ) + { + // There is a at least 2 free records in the extension + result = aSystemMaxLength; + } + else if ( curETelMaxLength > KMaxNumLengthNotUsingExt ) + { + // There is 1 free record in extension + // Number length can be at least KMaxNumLengthOneRecordFromExt + result = KMaxNumLengthOneRecordFromExt; + if ( curLength > KMaxNumLengthOneRecordFromExt ) + { + // Number already reserves 2 recors from extension + result = aSystemMaxLength; + } + } + else + { + // Extension is full. Number can use the records it already + // reserves. + if ( curLength > KMaxNumLengthOneRecordFromExt ) + { + // Number already uses 2 extension records + result = aSystemMaxLength; + } + else if ( curLength > KMaxNumLengthNotUsingExt ) + { + // Number already uses 1 extension record + result = KMaxNumLengthOneRecordFromExt; + } + else + { + // Number is not using extension records. + result = curETelMaxLength; + } + } + + // Finally add the length of '+' prefex and return. + return ++result; + } +} + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CVPbkSimCntField::CVPbkSimCntField +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CVPbkSimCntField::CVPbkSimCntField( TVPbkSimCntFieldType aType, + const MVPbkSimContact& aParentContact ) + : iType( aType ), + iParentContact( aParentContact ), + iMaxLength( KErrNotFound ) + { + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCntField::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CVPbkSimCntField::ConstructL() + { + iDataPtr.Set( KNullDesC ); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCntField::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CVPbkSimCntField* CVPbkSimCntField::NewL( TVPbkSimCntFieldType aType, + const MVPbkSimContact& aParentContact ) + { + CVPbkSimCntField* self = NewLC( aType, aParentContact ); + CleanupStack::Pop(); + return self; + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCntField::NewLC +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CVPbkSimCntField* CVPbkSimCntField::NewLC( TVPbkSimCntFieldType aType, + const MVPbkSimContact& aParentContact ) + { + CVPbkSimCntField* self = + new( ELeave ) CVPbkSimCntField( aType, aParentContact ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// Destructor +CVPbkSimCntField::~CVPbkSimCntField() + { + delete iData; + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCntField::SetDataL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVPbkSimCntField::SetDataL( const TDesC& aData ) + { + TPtr dataPtr( NULL, 0 ); + VPbkSimStoreImpl::CheckAndUpdateBufferSizeL( iData, dataPtr, + aData.Length() ); + dataPtr.Copy( aData ); + iDataPtr.Set( *iData ); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCntField::SetDataPtr +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CVPbkSimCntField::MaxDataLength() + { + if ( iMaxLength == KErrNotFound ) + { + iMaxLength = MaxLength( iType, iParentContact.ParentStore() ); + } + return iMaxLength; + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCntField::SetInitialSimDataL +// ----------------------------------------------------------------------------- +// +void CVPbkSimCntField::SetInitialSimDataL( const TDesC& aData ) + { + SetDataL( aData ); + + // Max length must be calculated for number types only because other + // types are not splitted in several records in SIM card. + if ( iType == EVPbkSimGsmNumber || iType == EVPbkSimAdditionalNumber ) + { + TInt currentMaxLength = MaxLength( iType, + iParentContact.ParentStore() ); + iMaxLength = CalculateNumberMaxLength( aData, currentMaxLength, + iParentContact.ParentStore().SystemPhoneNumberMaxLength() ); + } + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCntField::SetDataPtr +// ----------------------------------------------------------------------------- +// +void CVPbkSimCntField::SetDataPtr( TPtrC aDataPtr ) + { + iDataPtr.Set( aDataPtr ); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCntField::SetType +// ----------------------------------------------------------------------------- +// +void CVPbkSimCntField::SetType( TVPbkSimCntFieldType aType ) + { + iType = aType; + } +// End of File