phonebookengines/VirtualPhonebook/VPbkSimStoreImpl/src/CVPbkSimCntField.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
child 85 38bb213f60ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/VirtualPhonebook/VPbkSimStoreImpl/src/CVPbkSimCntField.cpp	Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,325 @@
+/*
+* 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 EVPbkSimAdditionalNumber1:  // FALLTHROUGH
+                case EVPbkSimAdditionalNumber2:  // FALLTHROUGH
+                case EVPbkSimAdditionalNumber3:  // FALLTHROUGH
+                case EVPbkSimAdditionalNumberLast: // same as EVPbkSimAdditionalNumber
+                    {
+                    result = uprop.iMaxAnrLength;
+                    break;
+                    }
+                case EVPbkSimReading:  // FALLTHROUGH
+                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 == EVPbkSimAdditionalNumber1
+            || iType == EVPbkSimAdditionalNumber2
+            || iType == EVPbkSimAdditionalNumber3
+            || iType == EVPbkSimAdditionalNumberLast ) // same as 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