phonebookengines/VirtualPhonebook/VPbkSimStoreImpl/src/CVPbkETelCntConverter.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
child 85 38bb213f60ba
equal deleted inserted replaced
62:5b6f26637ad3 63:f4a778e096c2
       
     1 /*
       
     2 * Copyright (c) 2002-2007 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:  A class that can convert sim contacts to etel contacts and vice
       
    15 *                versa
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include "CVPbkETelCntConverter.h"
       
    23 
       
    24 // From Virtual Phonebook
       
    25 #include "VPbkSimStoreImplError.h"
       
    26 #include <VPbkSimCntFieldTypes.hrh>
       
    27 #include <CVPbkSimCntField.h>
       
    28 #include <CVPbkSimContact.h>
       
    29 #include <VPbkSimStoreCommon.h>
       
    30 #include <CVPbkSimContactBuf.h>
       
    31 #include <VPbkDebug.h>
       
    32 
       
    33 // System includes
       
    34 #include <mpbutil.h> // CPhoneBookBuffer
       
    35 
       
    36 namespace   {
       
    37 // CONSTANTS
       
    38 // An amount of space to add to estimate of the size of the field
       
    39 // due to ETel padding bytes.
       
    40 const TInt KExtraFieldDataSpace = 3;
       
    41 // A buf size for the test buffer used to test CPhoneBookBuffer
       
    42 const TInt KTestBufSize = 20;
       
    43 }
       
    44 // ============================= LOCAL FUNCTIONS ===============================
       
    45 
       
    46 namespace {
       
    47 
       
    48 // -----------------------------------------------------------------------------
       
    49 // FieldConversion
       
    50 // Converts native sim field type to ETel field type
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 TUint8 FieldConversion( TVPbkSimCntFieldType aType )
       
    54     {
       
    55     TUint8 result = 0;
       
    56     switch ( aType )
       
    57         {
       
    58         case EVPbkSimName:
       
    59             {
       
    60             result = RMobilePhoneBookStore::ETagPBText;
       
    61             break;
       
    62             }
       
    63         case EVPbkSimGsmNumber: // FALLTHROUGH
       
    64         case EVPbkSimAdditionalNumber1:  // FALLTHROUGH
       
    65         case EVPbkSimAdditionalNumber2:  // FALLTHROUGH
       
    66         case EVPbkSimAdditionalNumber3:  // FALLTHROUGH
       
    67         case EVPbkSimAdditionalNumberLast:  // same as EVPbkSimAdditionalNumber
       
    68             {
       
    69             result = RMobilePhoneBookStore::ETagPBNumber;
       
    70             break;
       
    71             }
       
    72         case EVPbkSimNickName: // FALLTHROUGH
       
    73         case EVPbkSimReading: 
       
    74             {
       
    75             result = RMobilePhoneBookStore::ETagPBSecondName;
       
    76             break;
       
    77             }
       
    78         case EVPbkSimEMailAddress:
       
    79             {
       
    80             result = RMobilePhoneBookStore::ETagPBEmailAddress;
       
    81             break;
       
    82             }
       
    83         default:
       
    84             {
       
    85             // Do nothing
       
    86             break;
       
    87             }
       
    88         }
       
    89     return result;
       
    90     }
       
    91 
       
    92 // -----------------------------------------------------------------------------
       
    93 // FieldConversion
       
    94 // Converts ETel field type to native field type
       
    95 // -----------------------------------------------------------------------------
       
    96 //
       
    97 TVPbkSimCntFieldType FieldConversion( TUint8 aType )
       
    98     {
       
    99     TVPbkSimCntFieldType result = EVPbkSimUnknownType;
       
   100     switch ( aType )
       
   101         {
       
   102         case RMobilePhoneBookStore::ETagPBText:
       
   103             {
       
   104             result = EVPbkSimName;
       
   105             break;
       
   106             }
       
   107         case RMobilePhoneBookStore::ETagPBNumber:
       
   108             {
       
   109             result = EVPbkSimGsmNumber;
       
   110             break;
       
   111             }
       
   112         case RMobilePhoneBookStore::ETagPBSecondName:
       
   113             {
       
   114             result = EVPbkSimNickName;
       
   115             break;
       
   116             }
       
   117         case RMobilePhoneBookStore::ETagPBEmailAddress:
       
   118             {
       
   119             result = EVPbkSimEMailAddress;
       
   120             break;
       
   121             }
       
   122         default:
       
   123             {
       
   124             // Do nothing
       
   125             break;
       
   126             }
       
   127         }
       
   128     return result;
       
   129     }
       
   130     
       
   131 // -----------------------------------------------------------------------------
       
   132 // GetFieldData
       
   133 // Gets the first field data of given ETel field type
       
   134 // -----------------------------------------------------------------------------
       
   135 //
       
   136 template<class T>
       
   137 void GetFieldData( CPhoneBookBuffer& aETelBuffer, T& aData, TUint8 aFieldType )
       
   138     {
       
   139     TUint8 fieldTag;
       
   140 	CPhoneBookBuffer::TPhBkTagType dataType;
       
   141     while ( aETelBuffer.GetTagAndType( fieldTag, dataType) == KErrNone )
       
   142 		{
       
   143         if ( fieldTag == aFieldType )
       
   144             {
       
   145             aETelBuffer.GetValue( aData );
       
   146             return;
       
   147 			}
       
   148         else
       
   149             {
       
   150             aETelBuffer.SkipValue( dataType );
       
   151             }
       
   152         }
       
   153     }
       
   154 
       
   155 // -----------------------------------------------------------------------------
       
   156 // EstimateDataSize
       
   157 // Estimates the size that the data will take in ETel buffer
       
   158 // -----------------------------------------------------------------------------
       
   159 //
       
   160 inline TInt EstimateDataSize( const TArray<CVPbkSimCntField*>& aFieldArray )
       
   161     {
       
   162     // Initialize to zero size
       
   163     TInt size = 0;
       
   164     TInt count = aFieldArray.Count();
       
   165     for ( TInt i = 0; i < count; ++i )
       
   166         {
       
   167         // Add one byte for the field tag, then two bytes for data size
       
   168         // information, so 3 bytes will be added 
       
   169         size += KExtraFieldDataSpace;
       
   170         
       
   171         // Add the size of the data
       
   172         size += aFieldArray[i]->Data().Size();
       
   173         
       
   174         // ETel buffer uses word aligned data -> 0-3 padding bytes
       
   175         size += KExtraFieldDataSpace;
       
   176         }
       
   177     return size;
       
   178     }
       
   179 
       
   180 // -----------------------------------------------------------------------------
       
   181 // Adds a new data field to ETel contact
       
   182 // -----------------------------------------------------------------------------
       
   183 //
       
   184 inline TInt AddNewETelField( CPhoneBookBuffer& aETelBuffer, 
       
   185     CVPbkSimCntField& aField )
       
   186     {
       
   187     TUint8 etelType = FieldConversion( aField.Type() );
       
   188     __ASSERT_DEBUG( etelType != 0, VPbkSimStoreImpl::Panic( 
       
   189         VPbkSimStoreImpl::EInvalidVPbkToETelTypeConversion ) );
       
   190     const TDesC& data = aField.Data();
       
   191     if ( data.Length() > 0 )
       
   192         {
       
   193         if( aField.Type() == EVPbkSimAdditionalNumber1 
       
   194                 || aField.Type() == EVPbkSimAdditionalNumber2 
       
   195                 || aField.Type() == EVPbkSimAdditionalNumber3 
       
   196                 || aField.Type()== EVPbkSimAdditionalNumberLast ) // all these four types are all additional field types.
       
   197             {
       
   198             // Additional number needs own tag that must be added before data
       
   199             aETelBuffer.AddNewNumberTag();
       
   200             }
       
   201         return aETelBuffer.PutTagAndValue( etelType, data );    
       
   202         }
       
   203     return KErrNotFound;
       
   204     }
       
   205 
       
   206 } // unnamed
       
   207 
       
   208 // ============================ MEMBER FUNCTIONS ===============================
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // CVPbkETelCntConverter::CVPbkETelCntConverter
       
   212 // C++ default constructor can NOT contain any code, that
       
   213 // might leave.
       
   214 // -----------------------------------------------------------------------------
       
   215 //
       
   216 CVPbkETelCntConverter::CVPbkETelCntConverter()
       
   217     {
       
   218     }
       
   219 
       
   220 // -----------------------------------------------------------------------------
       
   221 // CVPbkETelCntConverter::ConstructL
       
   222 // Symbian 2nd phase constructor can leave.
       
   223 // -----------------------------------------------------------------------------
       
   224 //
       
   225 void CVPbkETelCntConverter::ConstructL()
       
   226     {
       
   227     // Create a Symbian utility for the contact data
       
   228     iETelBuffer = new( ELeave ) CPhoneBookBuffer;
       
   229     // Check how much space new entry tag takes and how much space
       
   230     // is needed for the contact that has only sim index
       
   231     HBufC8* testBuf = HBufC8::NewLC( KTestBufSize );
       
   232     TPtr8 ptr( testBuf->Des() );
       
   233     iETelBuffer->Set( &ptr );
       
   234     iETelBuffer->AddNewEntryTag();
       
   235     iNewEntryTagLength = ptr.Length();
       
   236     TUint16 exampleIndex = 1;
       
   237     iETelBuffer->PutTagAndValue( 
       
   238         RMobilePhoneBookStore::ETagPBAdnIndex, exampleIndex );
       
   239     // Safe solution -> double the space
       
   240     iMinContactLength = 2 * ptr.Length();
       
   241     CleanupStack::PopAndDestroy( testBuf );
       
   242     }
       
   243 
       
   244 // -----------------------------------------------------------------------------
       
   245 // CVPbkETelCntConverter::NewL
       
   246 // Two-phased constructor.
       
   247 // -----------------------------------------------------------------------------
       
   248 //
       
   249 EXPORT_C CVPbkETelCntConverter* CVPbkETelCntConverter::NewL()
       
   250     {
       
   251     CVPbkETelCntConverter* self = NewLC();
       
   252     CleanupStack::Pop();
       
   253     return self;
       
   254     }
       
   255 
       
   256 // -----------------------------------------------------------------------------
       
   257 // CVPbkETelCntConverter::NewLC
       
   258 // Two-phased constructor.
       
   259 // -----------------------------------------------------------------------------
       
   260 //
       
   261 EXPORT_C CVPbkETelCntConverter* CVPbkETelCntConverter::NewLC()
       
   262     {
       
   263     CVPbkETelCntConverter* self = new( ELeave ) CVPbkETelCntConverter;
       
   264     CleanupStack::PushL( self );
       
   265     self->ConstructL();
       
   266     return self;
       
   267     }
       
   268 
       
   269 // Destructor
       
   270 CVPbkETelCntConverter::~CVPbkETelCntConverter()
       
   271     {
       
   272     delete iETelBuffer;
       
   273     }
       
   274 
       
   275 // -----------------------------------------------------------------------------
       
   276 // CVPbkETelCntConverter::ConvertFromETelToVPbkSimContactsL
       
   277 // -----------------------------------------------------------------------------
       
   278 //
       
   279 void CVPbkETelCntConverter::ConvertFromETelToVPbkSimContactsL( 
       
   280     RPointerArray<CVPbkSimContactBuf>& aResultArray,
       
   281     TDes8& aETelContactData, MVPbkSimCntStore& aSimStore ) const
       
   282     {
       
   283     CleanupResetAndDestroyPushL( aResultArray );
       
   284     iETelBuffer->Set( &aETelContactData );
       
   285     User::LeaveIfError( StartRead() );
       
   286     
       
   287     TInt cntCounter = 0;
       
   288     TPtrC8 etelCnt( GetNextContactData( aETelContactData ) );
       
   289     while ( etelCnt.Length() > 0 )
       
   290         {
       
   291         CVPbkSimContactBuf* cnt = CVPbkSimContactBuf::NewLC( etelCnt, 
       
   292             aSimStore );
       
   293         aResultArray.AppendL( cnt );
       
   294         CleanupStack::Pop();
       
   295         ++cntCounter;
       
   296         etelCnt.Set( GetNextContactData( aETelContactData ) );
       
   297         }
       
   298 
       
   299     // Check if there was no contacts in the ETel descriptor
       
   300     if ( cntCounter == 0 )
       
   301         {
       
   302         User::Leave( KErrBadDescriptor );
       
   303         }
       
   304     CleanupStack::Pop( &aResultArray );
       
   305     }
       
   306 
       
   307 // -----------------------------------------------------------------------------
       
   308 // CVPbkETelCntConverter::ConvertFromETelToVPbkSimContactL
       
   309 // -----------------------------------------------------------------------------
       
   310 //
       
   311 void CVPbkETelCntConverter::ConvertFromETelToVPbkSimContactL( 
       
   312     TDes8& aETelContact, CVPbkSimContact& aEmptyContact ) const
       
   313     {
       
   314     CVPbkSimCntField* tmpField = 
       
   315         aEmptyContact.CreateFieldLC( EVPbkSimUnknownType );
       
   316     TInt error = KErrNone;
       
   317     const TInt count = DoFieldCount( aETelContact, error );
       
   318     User::LeaveIfError( error );
       
   319 
       
   320     for ( TInt i = 0; i < count; ++i )
       
   321         {
       
   322         FieldAt( aETelContact, i, *tmpField );
       
   323         CVPbkSimCntField* newField = 
       
   324             aEmptyContact.CreateFieldLC( tmpField->Type() );
       
   325         newField->SetInitialSimDataL( tmpField->Data() );
       
   326         aEmptyContact.AddFieldL( newField );
       
   327         CleanupStack::Pop( newField );
       
   328         }
       
   329     CleanupStack::PopAndDestroy( tmpField );
       
   330     aEmptyContact.SetSimIndex( SimIndex( aETelContact ) );
       
   331     }
       
   332 
       
   333 // -----------------------------------------------------------------------------
       
   334 // CVPbkETelCntConverter::ConvertFromVPbkSimFieldsToETelCntLC
       
   335 // -----------------------------------------------------------------------------
       
   336 //
       
   337 HBufC8* CVPbkETelCntConverter::ConvertFromVPbkSimFieldsToETelCntLC( 
       
   338     const TArray<CVPbkSimCntField*>& aFieldArray, TInt aSimIndex ) const
       
   339     {
       
   340     // Create a buffer for the ETel contact
       
   341     TInt size = iMinContactLength + EstimateDataSize( aFieldArray );
       
   342     HBufC8* buf = HBufC8::NewLC( size );
       
   343     TPtr8 ptr( buf->Des() );
       
   344     iETelBuffer->Set( &ptr );
       
   345     
       
   346     // Add new entry tag and the SIM index if not a new contact
       
   347     iETelBuffer->AddNewEntryTag();
       
   348     if ( aSimIndex != KVPbkSimStoreFirstFreeIndex )
       
   349         {
       
   350         iETelBuffer->PutTagAndValue( 
       
   351             RMobilePhoneBookStore::ETagPBAdnIndex, (TUint16) aSimIndex );
       
   352         }
       
   353 
       
   354     const TInt count = aFieldArray.Count();
       
   355     for( TInt i = 0; i < count; ++i )
       
   356         {
       
   357         TInt result = AddNewETelField( *iETelBuffer, *aFieldArray[i] );
       
   358         while ( result == KErrOverflow )
       
   359             {
       
   360             // If the buffer is too small for some reason -> double the size
       
   361             HBufC8* newBuf = buf->ReAllocL( 2 * buf->Size() );
       
   362             CleanupStack::Pop( buf );
       
   363             buf = newBuf;
       
   364             CleanupStack::PushL( buf );
       
   365             
       
   366             ptr.Set( buf->Des() );
       
   367             iETelBuffer->Set( &ptr );
       
   368             result = AddNewETelField( *iETelBuffer, *aFieldArray[i] );
       
   369             }
       
   370         }
       
   371     return buf;
       
   372     }
       
   373 
       
   374 // -----------------------------------------------------------------------------
       
   375 // CVPbkETelCntConverter::SimIndex
       
   376 // -----------------------------------------------------------------------------
       
   377 //
       
   378 TInt CVPbkETelCntConverter::SimIndex( TDes8& aETelContact ) const
       
   379     {
       
   380     iETelBuffer->Set( &aETelContact );
       
   381     if ( StartRead() == KErrNone )
       
   382         {
       
   383         TUint16 simIndex = 0;
       
   384         GetFieldData( *iETelBuffer, simIndex, 
       
   385             RMobilePhoneBookStore::ETagPBAdnIndex );
       
   386         if ( simIndex > 0 )
       
   387             {
       
   388             return simIndex;
       
   389             }
       
   390         else
       
   391             {
       
   392             return KVPbkSimStoreFirstFreeIndex;
       
   393             }
       
   394         }
       
   395     return KErrBadDescriptor;
       
   396     }
       
   397 
       
   398 // -----------------------------------------------------------------------------
       
   399 // CVPbkETelCntConverter::FieldCount
       
   400 // -----------------------------------------------------------------------------
       
   401 //
       
   402 TInt CVPbkETelCntConverter::FieldCount( TDes8& aETelContact ) const
       
   403     {
       
   404     // If client gives an invalid buffer KErrBadDescriptor is returned
       
   405     TInt error = KErrNone;
       
   406     TInt result = DoFieldCount( aETelContact, error );
       
   407     if ( error == KErrNone )
       
   408         {
       
   409         return result;
       
   410         }
       
   411     return error;
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CVPbkETelCntConverter::FieldAt
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 void CVPbkETelCntConverter::FieldAt( TDes8& aETelContact, TInt aIndex, 
       
   419     CVPbkSimCntField& aField ) const
       
   420     {
       
   421     iETelBuffer->Set( &aETelContact );
       
   422     if ( StartRead() == KErrNone )
       
   423         {
       
   424         for ( TInt i = 0; i <= aIndex; ++i )
       
   425             {
       
   426             GetNextField( aField );
       
   427             }
       
   428         }
       
   429     }
       
   430 
       
   431 // -----------------------------------------------------------------------------
       
   432 // CVPbkETelCntConverter::MoveToNextContact
       
   433 // Moves pointer to the next contact
       
   434 // -----------------------------------------------------------------------------
       
   435 //
       
   436 TBool CVPbkETelCntConverter::MoveToNextContact() const
       
   437     {
       
   438     TUint8 fieldTag;
       
   439 	CPhoneBookBuffer::TPhBkTagType dataType;
       
   440     while ( iETelBuffer->GetTagAndType( fieldTag, dataType) == KErrNone )
       
   441 		{
       
   442 		switch ( fieldTag )
       
   443 			{
       
   444 			case RMobilePhoneBookStore::ETagPBNewEntry:
       
   445 				{
       
   446                 return ETrue; 
       
   447 				}
       
   448             default:
       
   449                 {
       
   450                 iETelBuffer->SkipValue( dataType );
       
   451                 break;
       
   452                 }
       
   453             }
       
   454         }
       
   455     return EFalse;
       
   456     }
       
   457 
       
   458 // -----------------------------------------------------------------------------
       
   459 // CVPbkETelCntConverter::StartRead
       
   460 // Sets the pointer in the ETel buffer to the beginning of the first contact
       
   461 // Returns KErrBadDescriptor if the header was not found
       
   462 // -----------------------------------------------------------------------------
       
   463 //
       
   464 TInt CVPbkETelCntConverter::StartRead() const
       
   465     {
       
   466     iETelBuffer->StartRead();
       
   467 
       
   468     if ( MoveToNextContact() )
       
   469         {
       
   470         return KErrNone;
       
   471         }
       
   472     return KErrBadDescriptor;
       
   473     }
       
   474 
       
   475 // -----------------------------------------------------------------------------
       
   476 // CVPbkETelCntConverter::GetNextField
       
   477 // Gets the next field that has native support, returns EFalse if not found
       
   478 // -----------------------------------------------------------------------------
       
   479 //
       
   480 TBool CVPbkETelCntConverter::GetNextField( CVPbkSimCntField& aField ) const
       
   481     {
       
   482     TPtrC16 data;
       
   483     TUint8 fieldTag;
       
   484 	CPhoneBookBuffer::TPhBkTagType dataType;
       
   485 	TBool readingAnr = EFalse;
       
   486     while ( iETelBuffer->GetTagAndType( fieldTag, dataType) == KErrNone )
       
   487 		{
       
   488 		if ( fieldTag == RMobilePhoneBookStore::ETagPBAnrStart )
       
   489 		    {
       
   490 		    readingAnr = ETrue;
       
   491 		    }
       
   492         else if ( dataType == CPhoneBookBuffer::EPhBkTypeDes16 )
       
   493             {
       
   494             iETelBuffer->GetValue( data );
       
   495             TVPbkSimCntFieldType nativeType = FieldConversion( fieldTag );
       
   496             /// Text field of the ANR is not supported. If it's supported
       
   497             /// then the CVPbkSimCntField must have a label and it should
       
   498             /// be set here.
       
   499             if ( readingAnr && nativeType == EVPbkSimGsmNumber )
       
   500                 {
       
   501                 // VPbk SIM contact has an own type for additional number
       
   502                 nativeType = EVPbkSimAdditionalNumber;
       
   503                 }
       
   504             
       
   505             if ( nativeType != EVPbkSimUnknownType )
       
   506                 {
       
   507                 aField.SetDataPtr( data );
       
   508                 aField.SetType( nativeType );
       
   509                 return ETrue;
       
   510                 }            
       
   511 			}
       
   512         else
       
   513             {
       
   514             iETelBuffer->SkipValue( dataType );
       
   515             }
       
   516         }
       
   517     
       
   518     return EFalse;
       
   519     }
       
   520 
       
   521 // -----------------------------------------------------------------------------
       
   522 // CVPbkETelCntConverter::NumberOfFields
       
   523 // Returns the number of VPbk supported fields in the buffer
       
   524 // -----------------------------------------------------------------------------
       
   525 //
       
   526 TInt CVPbkETelCntConverter::NumberOfFields() const
       
   527     {
       
   528     TUint8 fieldTag;
       
   529 	CPhoneBookBuffer::TPhBkTagType dataType;
       
   530 	TBool readingAnr = EFalse;
       
   531 	TInt count = 0;
       
   532     while ( iETelBuffer->GetTagAndType( fieldTag, dataType) == KErrNone )
       
   533 		{
       
   534 		if ( fieldTag == RMobilePhoneBookStore::ETagPBAnrStart )
       
   535 		    {
       
   536 		    // Tag type is EPhBkTypeNoData so it's not needed to get value 
       
   537 		    readingAnr = ETrue;
       
   538 		    ++count;
       
   539 		    }
       
   540         else if ( dataType == CPhoneBookBuffer::EPhBkTypeDes16 )
       
   541             {
       
   542             TVPbkSimCntFieldType nativeType = FieldConversion( fieldTag );
       
   543             if ( !readingAnr && nativeType != EVPbkSimUnknownType )
       
   544                 {
       
   545                 ++count;
       
   546                 }
       
   547             // ANR number field ends the reading of ANR
       
   548             else if ( nativeType == EVPbkSimGsmNumber )
       
   549                 {
       
   550                 readingAnr = EFalse;
       
   551                 }
       
   552             // Data must be always read from the buffer to make it work
       
   553             iETelBuffer->SkipValue( dataType );
       
   554 			}
       
   555         else
       
   556             {
       
   557             iETelBuffer->SkipValue( dataType );
       
   558             }
       
   559         }
       
   560     
       
   561     return count;
       
   562     }
       
   563 
       
   564 // -----------------------------------------------------------------------------
       
   565 // GetNextContactData
       
   566 // Gets the next contact from the buffer that contains many contacts
       
   567 // -----------------------------------------------------------------------------
       
   568 //
       
   569 TPtrC8 CVPbkETelCntConverter::GetNextContactData( TDes8& aBuffer ) const
       
   570     {
       
   571     TInt newEntryTagLength = 1;
       
   572     TInt remainBefore = iETelBuffer->RemainingReadLength();
       
   573     
       
   574     if ( MoveToNextContact() )
       
   575         {
       
   576         TInt remainAfter = iETelBuffer->RemainingReadLength();
       
   577         TInt contactLength = remainBefore - remainAfter;
       
   578         TInt startPos = iETelBuffer->BufferLength() - remainBefore - 
       
   579             newEntryTagLength;
       
   580         return aBuffer.Mid( startPos, contactLength );
       
   581         }
       
   582     
       
   583     // 1 or 0 contacts left
       
   584     if ( remainBefore > 0 )
       
   585         {
       
   586         // 1 contact left
       
   587         TInt startPos = iETelBuffer->BufferLength() - remainBefore - 
       
   588             newEntryTagLength;
       
   589         return aBuffer.Mid( startPos );
       
   590         }
       
   591     else
       
   592         {
       
   593         // 0 contacts left, return zero length pointer
       
   594         return TPtrC8();
       
   595         }
       
   596     }
       
   597 
       
   598 // -----------------------------------------------------------------------------
       
   599 // DoFieldCount
       
   600 // Counts the number of fields of the contact
       
   601 // -----------------------------------------------------------------------------
       
   602 //
       
   603 TInt CVPbkETelCntConverter::DoFieldCount(
       
   604         TDes8& aETelContact, TInt& aError ) const
       
   605     {
       
   606     TInt count = 0;
       
   607     iETelBuffer->Set( &aETelContact );
       
   608 
       
   609     TInt result = StartRead();
       
   610     if ( result == KErrNone )
       
   611         {
       
   612         count = NumberOfFields();
       
   613         }
       
   614     aError = result;
       
   615 
       
   616     return count;
       
   617     }
       
   618 
       
   619 //  End of File