phonebookengines/VirtualPhonebook/VPbkEng/src/CVPbkContactLinkArray.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2005-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:  An array for contact links.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include "CVPbkContactLinkArray.h"
       
    21 
       
    22 #include "MVPbkContactStoreLoader.h"
       
    23 #include <MVPbkContactLink.h>
       
    24 #include <MVPbkStreamable.h>
       
    25 #include <TVPbkContactStoreUriPtr.h>
       
    26 #include <MVPbkContactStore.h>
       
    27 #include <MVPbkContactStoreProperties.h>
       
    28 #include <VPbkError.h>
       
    29 #include <MVPbkContactLinkPacking.h>
       
    30 #include <MVPbkContactStoreList.h>
       
    31 
       
    32 #include <s32mem.h>
       
    33 #include <badesca.h>
       
    34 #include <bamdesca.h>
       
    35 
       
    36 // packaged array static data
       
    37 namespace KLinkArrayStatic
       
    38     {
       
    39     /* streaming version 1 doesnt contain any optimizations */
       
    40     const TUint8 KVPbkPackagedLinkArrayVersionV1 = 1;
       
    41     /* streaming version 2 is optimized for memory usage */
       
    42     const TUint8 KVPbkPackagedLinkArrayVersionV2 = 2;    
       
    43     }
       
    44 
       
    45 namespace KLinkArrayExternalizeSizes
       
    46     {
       
    47     const TInt KVersionNumberSize = 1;
       
    48     const TInt KStoreUriCountSize = 2;
       
    49     const TInt KContactLinkCountSize = 4;
       
    50     const TInt KUriLengthSize = 2;
       
    51     const TInt KUriIndexSize = 2;
       
    52     const TInt KInternalPackedSize = 4;
       
    53     }
       
    54 
       
    55 namespace
       
    56     {
       
    57     const TUint8 KUriMarked = 1;
       
    58     const TUint8 KUriNotMarked = 0;
       
    59     const TInt KUriArrayGranularity = 4;
       
    60 
       
    61 #ifdef _DEBUG
       
    62     enum TPanic
       
    63         {
       
    64         EPreCond_IsUriMarked,
       
    65         EPreCond_MarkUri,
       
    66         EPreCond_RemoveUnmarkedUris,
       
    67         EPreCond_AppendStoreL
       
    68         };
       
    69         
       
    70     void Panic( TPanic aPanic )
       
    71         {
       
    72         _LIT(KPanicCat, "CVPbkContactLinkArray");
       
    73         User::Panic( KPanicCat, aPanic );
       
    74         }
       
    75 #endif // _DEBUG
       
    76     }
       
    77 
       
    78 /**
       
    79  * A helper class for sharing contact store URI descriptors.
       
    80  */
       
    81 NONSHARABLE_CLASS(CVPbkContactLinkArray::CStoreUris)
       
    82         :   public CBase
       
    83     {
       
    84     public:
       
    85         static CStoreUris* NewL();
       
    86         ~CStoreUris();
       
    87         
       
    88         /**
       
    89          * Appends the URI into array if if not appended earlier
       
    90          */
       
    91         void AppendIfNotFoundL( const MVPbkContactStore& aStore );
       
    92         /**
       
    93          * Appends the URI from the link if not appended earlier
       
    94          */
       
    95         void AppendIfNotFoundL( const MVPbkContactLink& aContactLink );
       
    96         /**
       
    97          * Appends empty URI to array
       
    98          */
       
    99         void AppendEmptyL();
       
   100         /**
       
   101          * @return the number of URIs
       
   102          */
       
   103         inline TInt Count() const;
       
   104         /**
       
   105          * @return a URI in the given Index
       
   106          */
       
   107         inline TPtrC At( TInt aIndex ) const;
       
   108         /**
       
   109          * @return the index of the store URI
       
   110          */
       
   111         inline TInt Find( const TDesC& aUri ) const;
       
   112         /**
       
   113          * @return the index of the URI or KErrNotFound
       
   114          */
       
   115         inline TInt Find( const MVPbkContactStore& aStore );
       
   116         /**
       
   117          * Destroys all URIs
       
   118          */
       
   119         void ResetAndDestroy();
       
   120         /**
       
   121          * @return ETrue if the URI is marked
       
   122          * @param aUri the URI to be checked
       
   123          */
       
   124         inline TBool IsUriMarked( const MVPbkContactStore& aStore );
       
   125         /**
       
   126          * Marks the URI
       
   127          * @param aUri the URI to be marked
       
   128          */
       
   129         void MarkUri( const MVPbkContactStore& aStore );
       
   130         /**
       
   131          * Unmarks all
       
   132          */
       
   133         void UnmarkAllUris();
       
   134         /**
       
   135          * Removes URIs that have no mark
       
   136          */
       
   137         void RemoveUnmarkedUris();
       
   138         
       
   139     private:
       
   140         CStoreUris();
       
   141         void ConstructL();
       
   142         void AppendStoreL( const MVPbkContactStore* aStore );
       
   143         
       
   144     private:
       
   145         /// Ref: An array for stores that are used to retrieve URIs
       
   146         RPointerArray<MVPbkContactStore> iStores;
       
   147         /// Own: an array of marks. This must be in balance with iStores
       
   148         RArray<TUint8> iMarkedUris;
       
   149     };
       
   150 
       
   151 // ---------------------------------------------------------------------------
       
   152 // CVPbkContactLinkArray::CStoreUris::CStoreUris
       
   153 // ---------------------------------------------------------------------------
       
   154 //
       
   155 inline CVPbkContactLinkArray::CStoreUris::CStoreUris()
       
   156         :   iStores( KUriArrayGranularity ), 
       
   157             iMarkedUris( KUriArrayGranularity )
       
   158     {    
       
   159     }
       
   160     
       
   161 // ---------------------------------------------------------------------------
       
   162 // CVPbkContactLinkArray::CStoreUris::NewL
       
   163 // ---------------------------------------------------------------------------
       
   164 //
       
   165 CVPbkContactLinkArray::CStoreUris* CVPbkContactLinkArray::CStoreUris::NewL()
       
   166     {
       
   167     CStoreUris* self = new( ELeave ) CStoreUris;
       
   168     return self;
       
   169     }
       
   170 
       
   171 // ---------------------------------------------------------------------------
       
   172 // CVPbkContactLinkArray::CStoreUris::~CStoreUris
       
   173 // ---------------------------------------------------------------------------
       
   174 //
       
   175 CVPbkContactLinkArray::CStoreUris::~CStoreUris()
       
   176     {
       
   177     iMarkedUris.Close();
       
   178     iStores.Close();
       
   179     }
       
   180 
       
   181 // ---------------------------------------------------------------------------
       
   182 // CVPbkContactLinkArray::CStoreUris::AppendIfNotFoundL
       
   183 // ---------------------------------------------------------------------------
       
   184 //    
       
   185 void CVPbkContactLinkArray::CStoreUris::AppendIfNotFoundL( 
       
   186         const MVPbkContactStore& aStore )
       
   187     {        
       
   188     if ( iStores.Find( &aStore ) == KErrNotFound )
       
   189         {
       
   190         AppendStoreL( &aStore );
       
   191         }
       
   192     }
       
   193     
       
   194 // ---------------------------------------------------------------------------
       
   195 // CVPbkContactLinkArray::CStoreUris::AppendIfNotFoundL
       
   196 // ---------------------------------------------------------------------------
       
   197 //    
       
   198 void CVPbkContactLinkArray::CStoreUris::AppendIfNotFoundL( 
       
   199         const MVPbkContactLink& aContactLink )
       
   200     {
       
   201     AppendIfNotFoundL( aContactLink.ContactStore() );
       
   202     }
       
   203 
       
   204 // ---------------------------------------------------------------------------
       
   205 // CVPbkContactLinkArray::CStoreUris::AppendEmptyL
       
   206 // ---------------------------------------------------------------------------
       
   207 //    
       
   208 void CVPbkContactLinkArray::CStoreUris::AppendEmptyL()
       
   209     {
       
   210     AppendStoreL( NULL );
       
   211     }
       
   212     
       
   213 // ---------------------------------------------------------------------------
       
   214 // CVPbkContactLinkArray::CStoreUris::Count
       
   215 // ---------------------------------------------------------------------------
       
   216 //    
       
   217 inline TInt CVPbkContactLinkArray::CStoreUris::Count() const
       
   218     {
       
   219     return iStores.Count();
       
   220     }
       
   221 
       
   222 // ---------------------------------------------------------------------------
       
   223 // CVPbkContactLinkArray::CStoreUris::At
       
   224 // ---------------------------------------------------------------------------
       
   225 //    
       
   226 inline TPtrC CVPbkContactLinkArray::CStoreUris::At( TInt aIndex ) const
       
   227     {
       
   228     const MVPbkContactStore* store = iStores[aIndex];
       
   229     if ( store )
       
   230         {
       
   231         return store->StoreProperties().Uri().UriDes();
       
   232         }
       
   233     else
       
   234         {
       
   235         return TPtrC( KNullDesC );
       
   236         }
       
   237     }
       
   238 
       
   239 // ---------------------------------------------------------------------------
       
   240 // CVPbkContactLinkArray::CStoreUris::FindL
       
   241 // ---------------------------------------------------------------------------
       
   242 //        
       
   243 TInt CVPbkContactLinkArray::CStoreUris::Find( const TDesC& aUri ) const
       
   244     {
       
   245     const TInt count = iStores.Count();
       
   246     for ( TInt i = 0; i < count; ++i )
       
   247         {
       
   248         if ( iStores[i] && iStores[i]->StoreProperties().Uri().Compare( aUri, 
       
   249              TVPbkContactStoreUriPtr::EContactStoreUriAllComponents ) == 0 )
       
   250             {
       
   251             return i;
       
   252             }
       
   253         }
       
   254     return KErrNotFound;
       
   255     }
       
   256 
       
   257 // ---------------------------------------------------------------------------
       
   258 // CVPbkContactLinkArray::CStoreUris::Find
       
   259 // ---------------------------------------------------------------------------
       
   260 //    
       
   261 TInt CVPbkContactLinkArray::CStoreUris::Find( 
       
   262         const MVPbkContactStore& aStore )
       
   263     {
       
   264     return iStores.Find( &aStore );
       
   265     }
       
   266 
       
   267 // ---------------------------------------------------------------------------
       
   268 // CVPbkContactLinkArray::CStoreUris::ResetAndDestroy
       
   269 // ---------------------------------------------------------------------------
       
   270 //    
       
   271 void CVPbkContactLinkArray::CStoreUris::ResetAndDestroy()
       
   272     {
       
   273     iStores.Reset();
       
   274     iMarkedUris.Reset();
       
   275     }
       
   276     
       
   277 // ---------------------------------------------------------------------------
       
   278 // CVPbkContactLinkArray::CStoreUris::IsUriMarked
       
   279 // ---------------------------------------------------------------------------
       
   280 //    
       
   281 TBool CVPbkContactLinkArray::CStoreUris::IsUriMarked( 
       
   282         const MVPbkContactStore& aStore )
       
   283     {
       
   284     __ASSERT_DEBUG( iMarkedUris.Count() == iStores.Count(),
       
   285         Panic( EPreCond_IsUriMarked ) );
       
   286     
       
   287     TInt pos = iStores.Find( &aStore );
       
   288     if ( pos != KErrNotFound &&
       
   289          iMarkedUris[pos] == KUriMarked )
       
   290         {
       
   291         return ETrue;
       
   292         }
       
   293     return EFalse;
       
   294     }
       
   295 
       
   296 // ---------------------------------------------------------------------------
       
   297 // CVPbkContactLinkArray::CStoreUris::MarkUri
       
   298 // ---------------------------------------------------------------------------
       
   299 //    
       
   300 void CVPbkContactLinkArray::CStoreUris::MarkUri( 
       
   301         const MVPbkContactStore& aStore )
       
   302     {
       
   303     __ASSERT_DEBUG( iMarkedUris.Count() == iStores.Count(),
       
   304         Panic( EPreCond_MarkUri ) );
       
   305     
       
   306     TInt pos = iStores.Find( &aStore );
       
   307     if ( pos != KErrNotFound )
       
   308         {
       
   309         iMarkedUris[pos] = KUriMarked;
       
   310         }
       
   311     }
       
   312     
       
   313 // ---------------------------------------------------------------------------
       
   314 // CVPbkContactLinkArray::CStoreUris::UnmarkAllUris
       
   315 // ---------------------------------------------------------------------------
       
   316 //    
       
   317 void CVPbkContactLinkArray::CStoreUris::UnmarkAllUris()
       
   318     {
       
   319     const TInt count = iMarkedUris.Count();
       
   320     for ( TInt i = 0; i < count; ++i )
       
   321         {
       
   322         iMarkedUris[i] = KUriNotMarked;
       
   323         }
       
   324     }
       
   325 
       
   326 // ---------------------------------------------------------------------------
       
   327 // CVPbkContactLinkArray::CStoreUris::RemoveUnmarkedUris
       
   328 // ---------------------------------------------------------------------------
       
   329 //    
       
   330 void CVPbkContactLinkArray::CStoreUris::RemoveUnmarkedUris()
       
   331     {
       
   332     __ASSERT_DEBUG( iMarkedUris.Count() == iStores.Count(),
       
   333         Panic( EPreCond_RemoveUnmarkedUris ) );
       
   334         
       
   335     const TInt count = iMarkedUris.Count();
       
   336     for ( TInt i = count - 1; i >= 0; --i )
       
   337         {
       
   338         if ( iMarkedUris[i] == KUriNotMarked )
       
   339             {
       
   340             iMarkedUris.Remove( i );
       
   341             iStores.Remove( i );
       
   342             }
       
   343         }
       
   344     }
       
   345 
       
   346 // ---------------------------------------------------------------------------
       
   347 // CVPbkContactLinkArray::CStoreUris::AppendStoreL
       
   348 // ---------------------------------------------------------------------------
       
   349 //    
       
   350 void CVPbkContactLinkArray::CStoreUris::AppendStoreL( 
       
   351         const MVPbkContactStore* aStore )
       
   352     {
       
   353     __ASSERT_DEBUG( iMarkedUris.Count() == iStores.Count(),
       
   354         Panic( EPreCond_AppendStoreL ) );
       
   355     User::LeaveIfError( iMarkedUris.Append( KUriNotMarked ) );
       
   356     TRAPD( res, iStores.AppendL( aStore ) );
       
   357     if ( res != KErrNone )
       
   358         {
       
   359         // If second AppendL leaves then return to the original state
       
   360         // by deleting the item appended in first AppendL
       
   361         iMarkedUris.Remove( iMarkedUris.Count() - 1 );
       
   362         User::Leave( res );
       
   363         }
       
   364     }
       
   365 
       
   366 // ======== MEMBER FUNCTIONS ========
       
   367 
       
   368 // ---------------------------------------------------------------------------
       
   369 // CVPbkContactLinkArray::CVPbkContactLinkArray
       
   370 // ---------------------------------------------------------------------------
       
   371 //
       
   372 inline CVPbkContactLinkArray::CVPbkContactLinkArray()
       
   373     {
       
   374     }
       
   375 
       
   376 // ---------------------------------------------------------------------------
       
   377 // CVPbkContactLinkArray::ConstructL
       
   378 // ---------------------------------------------------------------------------
       
   379 //
       
   380 inline void CVPbkContactLinkArray::ConstructL()
       
   381     {
       
   382     iStoreUris = CStoreUris::NewL();
       
   383     }
       
   384 
       
   385 // ---------------------------------------------------------------------------
       
   386 // CVPbkContactLinkArray::ConstructL
       
   387 // ---------------------------------------------------------------------------
       
   388 //
       
   389 inline void CVPbkContactLinkArray::ConstructL(
       
   390         const TDesC8& aPackedLinks, 
       
   391         const MVPbkContactStoreList& aStoreList)
       
   392     {
       
   393     iStoreUris = CStoreUris::NewL();
       
   394     // unencrypt the packed links descriptor to this array
       
   395     RDesReadStream readStream(aPackedLinks);
       
   396     readStream.PushL();
       
   397     InternalizeFromBufferL(readStream, aStoreList);
       
   398     CleanupStack::PopAndDestroy(&readStream);
       
   399     }
       
   400 
       
   401 // ---------------------------------------------------------------------------
       
   402 // CVPbkContactLinkArray::ConstructL
       
   403 // ---------------------------------------------------------------------------
       
   404 //
       
   405 inline void CVPbkContactLinkArray::ConstructL(
       
   406         RReadStream& aStream, 
       
   407         const MVPbkContactStoreList& aStoreList)
       
   408     {
       
   409     iStoreUris = CStoreUris::NewL();
       
   410     InternalizeFromBufferL( aStream, aStoreList );
       
   411     }
       
   412 
       
   413 // ---------------------------------------------------------------------------
       
   414 // CVPbkContactLinkArray::NewL
       
   415 // ---------------------------------------------------------------------------
       
   416 //
       
   417 EXPORT_C CVPbkContactLinkArray* CVPbkContactLinkArray::NewL()
       
   418     {
       
   419     CVPbkContactLinkArray* self = CVPbkContactLinkArray::NewLC();
       
   420     CleanupStack::Pop();
       
   421     return self;
       
   422     }
       
   423 
       
   424 // ---------------------------------------------------------------------------
       
   425 // CVPbkContactLinkArray::NewLC
       
   426 // ---------------------------------------------------------------------------
       
   427 //
       
   428 EXPORT_C CVPbkContactLinkArray* CVPbkContactLinkArray::NewLC()
       
   429     {
       
   430     CVPbkContactLinkArray* self = new(ELeave) CVPbkContactLinkArray();
       
   431     CleanupStack::PushL(self);
       
   432     self->ConstructL();
       
   433     return self;
       
   434     }
       
   435 
       
   436 // ---------------------------------------------------------------------------
       
   437 // CVPbkContactLinkArray::NewLC
       
   438 // ---------------------------------------------------------------------------
       
   439 //
       
   440 EXPORT_C CVPbkContactLinkArray* CVPbkContactLinkArray::NewLC(
       
   441         const TDesC8& aPackedLinks, 
       
   442         const MVPbkContactStoreList& aStoreList)
       
   443     {
       
   444     CVPbkContactLinkArray* self = new(ELeave) CVPbkContactLinkArray();
       
   445     CleanupStack::PushL(self);
       
   446     self->ConstructL(aPackedLinks, aStoreList);
       
   447     return self;
       
   448     }
       
   449 
       
   450 // ---------------------------------------------------------------------------
       
   451 // CVPbkContactLinkArray::NewLC
       
   452 // ---------------------------------------------------------------------------
       
   453 //
       
   454 EXPORT_C CVPbkContactLinkArray* CVPbkContactLinkArray::NewLC(
       
   455         RReadStream& aStream,
       
   456         const MVPbkContactStoreList& aStoreList)
       
   457     {
       
   458     CVPbkContactLinkArray* self = new(ELeave) CVPbkContactLinkArray();
       
   459     CleanupStack::PushL(self);
       
   460     self->ConstructL(aStream, aStoreList);
       
   461     return self;
       
   462     }
       
   463 
       
   464 // ---------------------------------------------------------------------------
       
   465 // CVPbkContactLinkArray::NewLC
       
   466 // ---------------------------------------------------------------------------
       
   467 //
       
   468 CVPbkContactLinkArray* CVPbkContactLinkArray::NewLC(
       
   469         RReadStream& aStream,
       
   470         MVPbkContactStoreLoader& aLoader )
       
   471     {
       
   472     CVPbkContactLinkArray* self = new( ELeave ) CVPbkContactLinkArray;
       
   473     CleanupStack::PushL( self );
       
   474     self->iStoreLoader = &aLoader;
       
   475     self->ConstructL( aStream, aLoader.ContactStoreListL() );
       
   476     return self;
       
   477     }
       
   478     
       
   479 // ---------------------------------------------------------------------------
       
   480 // CVPbkContactLinkArray::~CVPbkContactLinkArray
       
   481 // ---------------------------------------------------------------------------
       
   482 //
       
   483 CVPbkContactLinkArray::~CVPbkContactLinkArray()
       
   484     {
       
   485     iLinks.ResetAndDestroy();
       
   486     delete iStoreUris;
       
   487     }
       
   488 
       
   489 // ---------------------------------------------------------------------------
       
   490 // CVPbkContactLinkArray::Count
       
   491 // ---------------------------------------------------------------------------
       
   492 //
       
   493 TInt CVPbkContactLinkArray::Count() const
       
   494     {
       
   495     return iLinks.Count();
       
   496     }
       
   497 
       
   498 // ---------------------------------------------------------------------------
       
   499 // CVPbkContactLinkArray::At
       
   500 // ---------------------------------------------------------------------------
       
   501 //
       
   502 const MVPbkContactLink& CVPbkContactLinkArray::At(TInt aIndex) const
       
   503     {
       
   504     return *iLinks[aIndex];
       
   505     }
       
   506 
       
   507 // ---------------------------------------------------------------------------
       
   508 // CVPbkContactLinkArray::Find
       
   509 // ---------------------------------------------------------------------------
       
   510 //
       
   511 TInt CVPbkContactLinkArray::Find(const MVPbkContactLink& aLink) const
       
   512     {
       
   513     TInt result = KErrNotFound;
       
   514     
       
   515     const TInt count = Count();
       
   516     for (TInt i = 0; i < count; ++i)
       
   517         {
       
   518         if (aLink.IsSame(At(i)))
       
   519             {
       
   520             result = i;
       
   521             break;
       
   522             }
       
   523         }
       
   524     return result;
       
   525     }
       
   526 
       
   527 // ---------------------------------------------------------------------------
       
   528 // CVPbkContactLinkArray::PackLC
       
   529 //
       
   530 // Linkarray formats:
       
   531 //
       
   532 // Link array pack format 1:
       
   533 // stream := VersionNumber ContactLinkCount ContactLink*
       
   534 // VersionNumber := TUint8
       
   535 // ContactLinkCount := TUint32
       
   536 // ContactLink := UriLength UriDescriptor InternalPackedSize PackInternals
       
   537 // UriLength := TInt16
       
   538 // UriDescriptor := TChar*
       
   539 // InternalPackedSize := TUint32
       
   540 // PackInternals := TChar*
       
   541 //
       
   542 // Link array pack format 2:
       
   543 // stream := VersionNumber StoreUriCount StoreUri* ContactLinkCount ContactLink*
       
   544 // VersionNumber := TUint8
       
   545 // StoreUriCount := TUint16
       
   546 // StoreUri := UriLength UriDescriptor
       
   547 // UriLength := TUint16
       
   548 // UriDescriptor := TChar*
       
   549 // ContactLinkCount := TUint32
       
   550 // ContactLink := UriIndex InternalPackedSize PackInternals
       
   551 // UriIndex := TInt16
       
   552 // InternalPackedSize := TUint32
       
   553 // PackInternals := TChar*
       
   554 // ---------------------------------------------------------------------------
       
   555 HBufC8* CVPbkContactLinkArray::PackLC() const
       
   556     {
       
   557     const TInt bufferSize = DoCalculatePackedBufferSizeV2();
       
   558     HBufC8* packagedLinkArray = HBufC8::NewLC( bufferSize );
       
   559     TPtr8 bufPtr( packagedLinkArray->Des() );
       
   560     RDesWriteStream writeStream( bufPtr );
       
   561     writeStream.PushL();
       
   562     DoFillPackedBufferV2L( writeStream );
       
   563     writeStream.CommitL();
       
   564     CleanupStack::PopAndDestroy( &writeStream );
       
   565     
       
   566     return packagedLinkArray;
       
   567     }
       
   568 
       
   569 // ---------------------------------------------------------------------------
       
   570 // CVPbkContactLinkArray::Streamable
       
   571 // ---------------------------------------------------------------------------
       
   572 //
       
   573 const MVPbkStreamable* CVPbkContactLinkArray::Streamable() const
       
   574     {
       
   575     // persistent streaming is not supported
       
   576     return NULL;
       
   577     }
       
   578 
       
   579 // ---------------------------------------------------------------------------
       
   580 // CVPbkContactLinkArray::AppendL
       
   581 // ---------------------------------------------------------------------------
       
   582 //
       
   583 EXPORT_C void CVPbkContactLinkArray::AppendL( MVPbkContactLink* aLink )
       
   584     {
       
   585     if ( aLink )
       
   586         {
       
   587         iStoreUris->AppendIfNotFoundL( *aLink );
       
   588         iLinks.AppendL( aLink );
       
   589         }
       
   590     }
       
   591 
       
   592 // ---------------------------------------------------------------------------
       
   593 // CVPbkContactLinkArray::InsertL
       
   594 // ---------------------------------------------------------------------------
       
   595 //
       
   596 EXPORT_C void CVPbkContactLinkArray::InsertL( MVPbkContactLink* aLink, 
       
   597         TInt aIndex )
       
   598     {
       
   599     if ( aLink )
       
   600         {
       
   601         iStoreUris->AppendIfNotFoundL( *aLink );
       
   602         iLinks.InsertL( aLink, aIndex );
       
   603         }
       
   604     }
       
   605 
       
   606 // ---------------------------------------------------------------------------
       
   607 // CVPbkContactLinkArray::Remove
       
   608 // ---------------------------------------------------------------------------
       
   609 //
       
   610 EXPORT_C void CVPbkContactLinkArray::Remove( TInt aIndex )
       
   611     {
       
   612     iLinks.Remove(aIndex);
       
   613     }
       
   614 
       
   615 // ---------------------------------------------------------------------------
       
   616 // CVPbkContactLinkArray::Delete
       
   617 // ---------------------------------------------------------------------------
       
   618 //    
       
   619 EXPORT_C void CVPbkContactLinkArray::Delete( TInt aIndex )
       
   620     {
       
   621     MVPbkContactLink* link = iLinks[aIndex];
       
   622     Remove( aIndex );
       
   623     delete link;
       
   624     }
       
   625 
       
   626 // ---------------------------------------------------------------------------
       
   627 // CVPbkContactLinkArray::ResetAndDestroy
       
   628 // ---------------------------------------------------------------------------
       
   629 //    
       
   630 EXPORT_C void CVPbkContactLinkArray::ResetAndDestroy()
       
   631     {
       
   632     iLinks.ResetAndDestroy();
       
   633     iStoreUris->ResetAndDestroy();
       
   634     }
       
   635 
       
   636 // ---------------------------------------------------------------------------
       
   637 // CVPbkContactLinkArray::Reset
       
   638 // ---------------------------------------------------------------------------
       
   639 //        
       
   640 EXPORT_C void CVPbkContactLinkArray::Reset()
       
   641     {
       
   642     iLinks.Reset();
       
   643     iStoreUris->ResetAndDestroy();
       
   644     }
       
   645 
       
   646 // ---------------------------------------------------------------------------
       
   647 // CVPbkContactLinkArray::PackedBufferSize
       
   648 // ---------------------------------------------------------------------------
       
   649 //        
       
   650 EXPORT_C TInt CVPbkContactLinkArray::PackedBufferSize() const
       
   651     {
       
   652     return DoCalculatePackedBufferSizeV2(); // V2
       
   653     }
       
   654 
       
   655 // ---------------------------------------------------------------------------
       
   656 // CVPbkContactLinkArray::DoCalculatePackedBufferSizeV2
       
   657 // NOTE: This function also removes URIs that are not refered from links
       
   658 // ---------------------------------------------------------------------------
       
   659 //
       
   660 TInt CVPbkContactLinkArray::DoCalculatePackedBufferSizeV2() const
       
   661     {
       
   662     // Unmark all URIs
       
   663     iStoreUris->UnmarkAllUris();
       
   664     
       
   665     TInt bufferSize = KLinkArrayExternalizeSizes::KVersionNumberSize +
       
   666         KLinkArrayExternalizeSizes::KStoreUriCountSize + 
       
   667         KLinkArrayExternalizeSizes::KContactLinkCountSize;
       
   668     
       
   669     const TInt linkCount = iLinks.Count();
       
   670     for (TInt i = 0; i < linkCount; ++i)
       
   671         {
       
   672         const MVPbkContactLink& link = *iLinks[i];
       
   673         const MVPbkContactStore& store = link.ContactStore();
       
   674         // Add URI length if not added before
       
   675         if ( !iStoreUris->IsUriMarked( store ) )
       
   676             {
       
   677             bufferSize += KLinkArrayExternalizeSizes::KUriLengthSize;
       
   678             bufferSize += store.StoreProperties().Uri().UriDes().Size();
       
   679             // Mark URI so that its length is not added again
       
   680             iStoreUris->MarkUri( store );
       
   681             }
       
   682         // Add the link internals size
       
   683         bufferSize += KLinkArrayExternalizeSizes::KUriIndexSize;
       
   684         bufferSize += KLinkArrayExternalizeSizes::KInternalPackedSize;
       
   685         bufferSize += link.Packing().InternalPackedSize();
       
   686         }
       
   687 
       
   688     // Remove URIs that are not used
       
   689     iStoreUris->RemoveUnmarkedUris();
       
   690     // Reset the state of iStoreUris marked URIs
       
   691     iStoreUris->UnmarkAllUris();
       
   692     
       
   693     return bufferSize;
       
   694     }
       
   695 
       
   696 // ---------------------------------------------------------------------------
       
   697 // CVPbkContactLinkArray::DoFillPackedBufferV2L
       
   698 // ---------------------------------------------------------------------------
       
   699 //
       
   700 void CVPbkContactLinkArray::DoFillPackedBufferV2L(
       
   701         RWriteStream& aWriteStream) const
       
   702     {
       
   703     // write version number
       
   704     aWriteStream.WriteUint8L(
       
   705         KLinkArrayStatic::KVPbkPackagedLinkArrayVersionV2);
       
   706     // write store URI count
       
   707     const TInt uriCount = iStoreUris->Count();
       
   708     aWriteStream.WriteUint16L( uriCount );
       
   709     // write store URIs
       
   710     for ( TInt i = 0; i < uriCount; ++i )
       
   711         {
       
   712         TPtrC uriPtr( iStoreUris->At( i ) );
       
   713         const TInt uriLength = uriPtr.Length();
       
   714         aWriteStream.WriteUint16L( uriLength );
       
   715         aWriteStream.WriteL( uriPtr, uriLength );
       
   716         }
       
   717     const TInt linkCount = iLinks.Count();
       
   718     // write the contact link count to the stream
       
   719     aWriteStream.WriteUint32L( linkCount );
       
   720     // write links
       
   721     for (TInt i = 0; i < linkCount; ++i)
       
   722         {
       
   723         const MVPbkContactLink& link = *iLinks[i];
       
   724         const TInt uriIndex = iStoreUris->Find( link.ContactStore() );
       
   725         // write URI index
       
   726         aWriteStream.WriteInt16L( uriIndex );
       
   727         // write URI internal size
       
   728         aWriteStream.WriteUint32L( link.Packing().InternalPackedSize() );
       
   729         // write internals
       
   730         link.Packing().PackInternalsL(aWriteStream);
       
   731         }
       
   732     }
       
   733 
       
   734 // ---------------------------------------------------------------------------
       
   735 // CVPbkContactLinkArray::InternalizeFromBufferL
       
   736 // ---------------------------------------------------------------------------
       
   737 //
       
   738 void CVPbkContactLinkArray::InternalizeFromBufferL( 
       
   739 		RReadStream& aReadStream, 
       
   740         const MVPbkContactStoreList& aStoreList )
       
   741     {
       
   742     // check correct version number of link array
       
   743     const TInt versionNumber = aReadStream.ReadUint8L();
       
   744     if ( versionNumber == KLinkArrayStatic::KVPbkPackagedLinkArrayVersionV1 )
       
   745         {
       
   746         DoInternalizeFromBufferL( aReadStream, aStoreList );
       
   747         }
       
   748     else if ( versionNumber == 
       
   749               KLinkArrayStatic::KVPbkPackagedLinkArrayVersionV2 )
       
   750         {
       
   751         DoInternalizeFromBufferV2L( aReadStream, aStoreList );
       
   752         }
       
   753     else
       
   754         {
       
   755         // Invalid link array version
       
   756         User::Leave( KErrArgument );
       
   757         }
       
   758     }
       
   759 
       
   760 // ---------------------------------------------------------------------------
       
   761 // CVPbkContactLinkArray::DoInternalizeFromBufferL
       
   762 // Version 1
       
   763 // ---------------------------------------------------------------------------
       
   764 //
       
   765 void CVPbkContactLinkArray::DoInternalizeFromBufferL(
       
   766         RReadStream& aReadStream, 
       
   767         const MVPbkContactStoreList& aStoreList)
       
   768     {
       
   769     // read contact link count from the stream
       
   770     const TInt contactLinkCount = aReadStream.ReadUint32L();
       
   771 
       
   772     // read each contact link from the stream
       
   773     for (TInt i = 0; i < contactLinkCount; ++i)
       
   774         {
       
   775         // read the store URI
       
   776         const TInt uriLength = aReadStream.ReadUint16L();
       
   777         HBufC* uriBuffer = HBufC::NewLC(uriLength);
       
   778         TPtr uriPtr = uriBuffer->Des();
       
   779         aReadStream.ReadL(uriPtr, uriLength);
       
   780         // find the store corresponding to the URI
       
   781         MVPbkContactStore* store =
       
   782             aStoreList.Find(TVPbkContactStoreUriPtr(uriPtr));
       
   783         CleanupStack::PopAndDestroy(uriBuffer);
       
   784 
       
   785         const TInt internalPackedSize = aReadStream.ReadUint32L();
       
   786         if(store)
       
   787             {
       
   788             // create link and add it to this array
       
   789             MVPbkContactLink* link = 
       
   790                 store->CreateLinkFromInternalsLC(aReadStream);
       
   791             AppendL(link);
       
   792             CleanupStack::Pop(); // link
       
   793             }
       
   794         else
       
   795             {
       
   796             // skip PackInternals that are unknown
       
   797             aReadStream.ReadL(internalPackedSize);
       
   798             }
       
   799         }
       
   800     }
       
   801 
       
   802 // ---------------------------------------------------------------------------
       
   803 // CVPbkContactLinkArray::DoInternalizeFromBufferV2L
       
   804 // Version 2
       
   805 // ---------------------------------------------------------------------------
       
   806 //
       
   807 void CVPbkContactLinkArray::DoInternalizeFromBufferV2L(
       
   808         RReadStream& aReadStream, 
       
   809         const MVPbkContactStoreList& aStoreList)
       
   810     {
       
   811     // Read store URI count
       
   812     TInt uriCount = aReadStream.ReadUint16L();
       
   813     // Read URIs
       
   814     for ( TInt i = 0; i < uriCount; ++i )
       
   815         {
       
   816         const TInt uriLength = aReadStream.ReadUint16L();
       
   817         HBufC* uriBuffer = HBufC::NewLC(uriLength);
       
   818         TPtr uriPtr = uriBuffer->Des();
       
   819         aReadStream.ReadL( uriPtr, uriLength );
       
   820         MVPbkContactStore* store = aStoreList.Find( uriPtr );
       
   821         if ( !store && iStoreLoader )
       
   822             {
       
   823             // Try to load the store
       
   824             iStoreLoader->LoadContactStoreL( uriPtr );
       
   825             store = aStoreList.Find( uriPtr );
       
   826             }
       
   827         
       
   828         if ( store )
       
   829             {
       
   830             iStoreUris->AppendIfNotFoundL( *store );
       
   831             }
       
   832         else
       
   833             {
       
   834             // Append empty URI to keep ÜRI indexes valid
       
   835             iStoreUris->AppendEmptyL();
       
   836             }
       
   837         CleanupStack::PopAndDestroy( uriBuffer );
       
   838         }
       
   839     
       
   840     if ( uriCount != iStoreUris->Count() )
       
   841         {
       
   842         // There must be as many items in the iStoreUris as uriCount
       
   843         // because otherwise URI indexes are not valid. We cannot
       
   844         // continue reading link data in that case.
       
   845         User::Leave( KErrCorrupt );
       
   846         }
       
   847     
       
   848     // read contact link count from the stream
       
   849     const TInt contactLinkCount = aReadStream.ReadUint32L();
       
   850     // read each contact link from the stream
       
   851     for (TInt i = 0; i < contactLinkCount; ++i)
       
   852         {
       
   853         // read the store URI index
       
   854         const TInt uriIndex = aReadStream.ReadInt16L();
       
   855         // read the size of the internals
       
   856         const TInt internalPackedSize = aReadStream.ReadUint32L();
       
   857         if ( uriIndex >= 0 && uriIndex < uriCount )
       
   858             {
       
   859             const TDesC& uri = iStoreUris->At( uriIndex );
       
   860             // find the store corresponding to the URI
       
   861             MVPbkContactStore* store = aStoreList.Find( uri );
       
   862             if( store )
       
   863                 {
       
   864                 // create link and add it to this array
       
   865                 MVPbkContactLink* link = 
       
   866                     store->CreateLinkFromInternalsLC( aReadStream );
       
   867                 AppendL( link );
       
   868                 CleanupStack::Pop(); // link
       
   869                 }
       
   870             else
       
   871                 {
       
   872                 // skip PackInternals that are unknown
       
   873                 aReadStream.ReadL( internalPackedSize );
       
   874                 }
       
   875             }
       
   876         else
       
   877             {
       
   878             // skip PackInternals that are unknown
       
   879             aReadStream.ReadL( internalPackedSize );
       
   880             }
       
   881         }
       
   882     }
       
   883 // end of file