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