activityfw/storage/server/src/afstorage.cpp
changeset 104 9b022b1f357c
child 107 b34d53f6acdf
equal deleted inserted replaced
103:b99b84bcd2d1 104:9b022b1f357c
       
     1 /*
       
     2 * Copyright (c) 2009 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:
       
    15 *
       
    16 */
       
    17 #include "afstorage.h"
       
    18 #include <bautils.h>
       
    19 #include <hash.h>
       
    20 #include <s32mem.h>
       
    21 
       
    22 #include "afqueries.h"
       
    23 #include "afentry.h"
       
    24 
       
    25 _LIT(KDbName, "activity.db");
       
    26 _LIT(KDbDrive, "c:");
       
    27 const TInt KMaxPathLength = 256;
       
    28 
       
    29 _LIT(KNonPersistent, "non_persistent\\");
       
    30 _LIT(KPersistent, "persistent\\");
       
    31 _LIT(KUidFormat, "%+08x\\");
       
    32 _LIT(KExtFormat, ".mbm");
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 /**
       
    36  * Constructor for performing 1st stage construction
       
    37  * @param session - initialized session to file system
       
    38  */
       
    39 CAfStorage::CAfStorage(RFs& session)
       
    40 :
       
    41 mFsSession(session)
       
    42 {
       
    43     // No implementation required
       
    44 }
       
    45 
       
    46 // -----------------------------------------------------------------------------
       
    47 /**
       
    48  * Destructor.
       
    49  */
       
    50 CAfStorage::~CAfStorage()
       
    51 {
       
    52 }
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 /**
       
    56  * Two-phased constructor.
       
    57  * @param session - initialized session to file system
       
    58  */
       
    59 CAfStorage* CAfStorage::NewL(RFs& session)
       
    60 {
       
    61     CAfStorage* self = new (ELeave) CAfStorage(session);
       
    62     CleanupStack::PushL(self);
       
    63     self->ConstructL();
       
    64     CleanupStack::Pop(); // self;
       
    65     return self;
       
    66 }
       
    67 
       
    68 // -----------------------------------------------------------------------------
       
    69 /**
       
    70  * EPOC default constructor for performing 2nd stage construction
       
    71  */
       
    72 void CAfStorage::ConstructL()
       
    73 {
       
    74     RBuf path;
       
    75     CleanupClosePushL( path );
       
    76     path.CreateL(KMaxPathLength);
       
    77     User::LeaveIfError(mFsSession.PrivatePath(path ));
       
    78     path.Append(KDbName);
       
    79     path.Insert(0, KDbDrive);
       
    80     BaflUtils::EnsurePathExistsL(mFsSession, path);
       
    81     BaflUtils::FileExists(mFsSession, path) ? OpenDbL(path) : CreateDbL(path);
       
    82     CleanupStack::PopAndDestroy(&path);
       
    83 
       
    84     DeleteNonPersistentActivitiesL();
       
    85 }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 /**
       
    89  * Create database and its structure
       
    90  * @param databaseFile - database file path
       
    91  */
       
    92 void CAfStorage::CreateDbL(const TDesC& databaseFile)
       
    93 {
       
    94     mFileStore = CPermanentFileStore::ReplaceL(mFsSession,
       
    95                                                databaseFile,
       
    96                                                EFileRead|EFileWrite);
       
    97     mFileStore->SetTypeL(mFileStore->Layout());// Set file store type
       
    98     TStreamId id = mActDb.CreateL(mFileStore);// Create stream object
       
    99     mFileStore->SetRootL(id);// Keep database id as root of store
       
   100     mFileStore->CommitL();// Complete creation by commiting
       
   101     CreateTableL();
       
   102 }
       
   103 
       
   104 // -----------------------------------------------------------------------------
       
   105 /**
       
   106  * Open database
       
   107  * @param databaseFile - database file path
       
   108  */
       
   109 void CAfStorage::OpenDbL(const TDesC& databaseFile)
       
   110 {
       
   111     mFileStore = CPermanentFileStore::OpenL(mFsSession,
       
   112                                             databaseFile,
       
   113                                             EFileRead|EFileWrite);
       
   114     mFileStore->SetTypeL(mFileStore->Layout()); /* Set file store type*/
       
   115     mActDb.OpenL(mFileStore,mFileStore->Root());
       
   116     CDbTableNames* tables = mActDb.TableNamesL();
       
   117     CleanupStack::PushL(tables);
       
   118     if (0 == tables->Count()) {
       
   119         CreateTableL();
       
   120     }
       
   121     CleanupStack::PopAndDestroy(tables);
       
   122 }
       
   123 
       
   124 // -----------------------------------------------------------------------------
       
   125 /**
       
   126  * Create database structure
       
   127  */
       
   128 void CAfStorage::CreateTableL()
       
   129 {
       
   130     // Add the columns to column set
       
   131     CDbColSet* actColSet = CDbColSet::NewLC();
       
   132 
       
   133     TDbCol appName(KApplicationColumnName, EDbColInt64);
       
   134     appName.iAttributes = TDbCol::ENotNull;
       
   135     actColSet->AddL(appName);
       
   136 
       
   137     TDbCol actName(KActivityColumnName, EDbColText16);// Using default length
       
   138     actName.iAttributes = TDbCol::ENotNull;
       
   139     actColSet->AddL(actName);
       
   140 
       
   141     TDbCol actFlags(KFlagsColumnName, EDbColInt32);
       
   142     actFlags.iAttributes = TDbCol::ENotNull;
       
   143     actColSet->AddL(actFlags);
       
   144 
       
   145     actColSet->AddL(TDbCol(KDataColumnName, EDbColLongBinary));// Stream Data
       
   146 
       
   147     // Create the table
       
   148     User::LeaveIfError(mActDb.CreateTable(KActivityTableName,
       
   149                                          *actColSet));
       
   150 
       
   151     CleanupStack::PopAndDestroy(actColSet);
       
   152 }
       
   153 
       
   154 // -----------------------------------------------------------------------------
       
   155 /**
       
   156  * Delete non-persistent activities
       
   157  */
       
   158 void CAfStorage::DeleteNonPersistentActivitiesL()
       
   159 {
       
   160     HBufC *query(BuildQueryLC(KDeleteNonPersistentActivities(), CAfEntry::Persistent, KNullDesC));
       
   161     User::LeaveIfError(mActDb.Execute(*query));
       
   162     RBuf privatePath;
       
   163     CleanupClosePushL(privatePath);
       
   164     privatePath.CreateL(KMaxPathLength);
       
   165     StoragePathL(privatePath, Fs(), FALSE);
       
   166     CFileMan *fileMan = CFileMan::NewL(Fs());
       
   167     TInt i = fileMan->RmDir(privatePath);
       
   168     delete fileMan;
       
   169     CleanupStack::PopAndDestroy(&privatePath);
       
   170     CleanupStack::PopAndDestroy(query);
       
   171 }
       
   172 
       
   173 // -----------------------------------------------------------------------------
       
   174 /**
       
   175  * Register new activity
       
   176  * @param appId - application id
       
   177  * @param actId - activity id
       
   178  * @param flags - activity flags
       
   179  * @param imgSrc - activity thumbnail source
       
   180  * @param privateData - activity private data
       
   181  * @param publicData - activity public data
       
   182  */
       
   183 void CAfStorage::AddActivityL(CAfEntry& entry)
       
   184 {
       
   185     //verify if row already exists
       
   186     TInt errNo(KErrNone);
       
   187     RDbView view;
       
   188     CleanupClosePushL(view);
       
   189     TRAP( errNo, GetActivityForUpdateL(view, entry.ApplicationId(), entry.ActivityId()));
       
   190     if (KErrNone == errNo) {
       
   191         User::Leave(KErrAlreadyExists);
       
   192     }
       
   193     CleanupStack::PopAndDestroy(&view);
       
   194 
       
   195     //write table
       
   196     RDbTable table;
       
   197     CleanupClosePushL(table);
       
   198     User::LeaveIfError(table.Open(mActDb, KActivityTableName, table.EUpdatable));
       
   199     CDbColSet *row = table.ColSetL();
       
   200     CleanupStack::PushL(row);
       
   201 
       
   202     table.InsertL();
       
   203     TRAP(errNo,
       
   204     table.SetColL(row->ColNo(KApplicationColumnName), TInt64(entry.ApplicationId()));
       
   205     table.SetColL(row->ColNo(KActivityColumnName), entry.ActivityId());
       
   206     table.SetColL(row->ColNo(KFlagsColumnName), entry.Flags());
       
   207     ExternalizeDataL(table, entry, row->ColNo(KDataColumnName));
       
   208     table.PutL();)
       
   209     if (KErrNone != errNo) {
       
   210         table.Cancel();
       
   211         User::Leave(errNo);
       
   212     }
       
   213     CleanupStack::PopAndDestroy(row);
       
   214     CleanupStack::PopAndDestroy(&table);
       
   215 }
       
   216 
       
   217 // -----------------------------------------------------------------------------
       
   218 /**
       
   219  * Update activity
       
   220  * @param entry - activity data
       
   221  */
       
   222 void CAfStorage::UpdateActivityL(CAfEntry& entry)
       
   223 {
       
   224     RDbView view;
       
   225     CleanupClosePushL(view);
       
   226     GetActivityForUpdateL(view, entry.ApplicationId(), entry.ActivityId());
       
   227     view.UpdateL();
       
   228     TRAPD(errNo,
       
   229     CDbColSet* colSet = view.ColSetL();
       
   230     CleanupStack::PushL(colSet);
       
   231 
       
   232     view.SetColL(colSet->ColNo(KFlagsColumnName), entry.Flags());
       
   233     ExternalizeDataL(view, entry, colSet->ColNo(KDataColumnName));
       
   234 
       
   235     view.PutL();
       
   236     if (KErrNone != errNo) {
       
   237         view.Cancel();
       
   238         User::Leave(errNo);
       
   239     }
       
   240     CleanupStack::PopAndDestroy(colSet);)
       
   241 
       
   242     if (KErrNone != errNo) {
       
   243         view.Cancel();
       
   244         User::Leave(errNo);
       
   245     }
       
   246     CleanupStack::PopAndDestroy(&view);
       
   247 }
       
   248 
       
   249 // -----------------------------------------------------------------------------
       
   250 /**
       
   251  * Delete activity
       
   252  * @param appId - application id
       
   253  * @param actId - activity id
       
   254  */
       
   255 void CAfStorage::DeleteActivityL(CAfEntry& entry)
       
   256 {
       
   257     HBufC *query(DeleteRowLC(entry.ApplicationId(), entry.ActivityId()));
       
   258     User::LeaveIfError(mActDb.Execute(*query));
       
   259     CleanupStack::PopAndDestroy(query);
       
   260 }
       
   261 
       
   262 // -----------------------------------------------------------------------------
       
   263 //
       
   264 // -----------------------------------------------------------------------------
       
   265 //
       
   266 void CAfStorage::DeleteActivitiesL(CAfEntry& entry)
       
   267 {
       
   268     HBufC *query(DeleteRowsLC(entry.ApplicationId()));
       
   269     User::LeaveIfError(mActDb.Execute(*query));
       
   270     RBuf privatePath;
       
   271     CleanupClosePushL(privatePath);
       
   272     privatePath.CreateL(KMaxPathLength);
       
   273     AppStoragePathL(privatePath, Fs(), entry.ApplicationId(), FALSE);
       
   274     CFileMan *fileMan = CFileMan::NewL(Fs());
       
   275     CleanupStack::PushL(fileMan);
       
   276     fileMan->RmDir(privatePath);
       
   277     privatePath.Zero();
       
   278     
       
   279     AppStoragePathL(privatePath, Fs(), entry.ApplicationId(), TRUE);
       
   280     fileMan->RmDir(privatePath);
       
   281     
       
   282     CleanupStack::PopAndDestroy(fileMan);
       
   283     CleanupStack::PopAndDestroy(&privatePath);
       
   284     CleanupStack::PopAndDestroy(query);
       
   285 }
       
   286 
       
   287 // -----------------------------------------------------------------------------
       
   288 //
       
   289 // -----------------------------------------------------------------------------
       
   290 //
       
   291 void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst)
       
   292 {
       
   293     ActivitiesL(dst, KSelectRows(), CAfEntry::Public);
       
   294 }
       
   295 
       
   296 // -----------------------------------------------------------------------------
       
   297 /**
       
   298  * Serialize application activity into the buffer
       
   299  * @param dst - destination buffer
       
   300  * @param appId - application id
       
   301  */
       
   302 void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst,TInt appId)
       
   303 {
       
   304     HBufC *query(SelectRowsLC(appId));
       
   305     ActivitiesL(dst, *query, CAfEntry::Private);
       
   306     CleanupStack::PopAndDestroy(query);
       
   307 }
       
   308 
       
   309 // -----------------------------------------------------------------------------
       
   310 /**
       
   311  * Serialize application activity into the buffer
       
   312  * @param dst - destination entry
       
   313  * @param src - condition pattern
       
   314  */
       
   315 void CAfStorage::ActivityL(RPointerArray<CAfEntry> &dst, CAfEntry& src)
       
   316 {
       
   317     HBufC *query = SelectRowLC(src.ApplicationId(), src.ActivityId());
       
   318     ActivitiesL(dst, *query, CAfEntry::Private, 1);
       
   319     if (0 >= dst.Count()) {
       
   320         User::Leave(KErrNotFound);
       
   321     }
       
   322     CleanupStack::PopAndDestroy(query);
       
   323 }
       
   324 
       
   325 // -----------------------------------------------------------------------------
       
   326 /**
       
   327  * Provide initialized file system session
       
   328  * @return file system session
       
   329  */
       
   330 RFs& CAfStorage::Fs()
       
   331 {
       
   332     return mFsSession;
       
   333 }
       
   334 
       
   335 // -----------------------------------------------------------------------------
       
   336 /**
       
   337  * Format query to select activity row
       
   338  * @param appId - application id
       
   339  * @param actId - activity id
       
   340  * @return formated sql query
       
   341  */
       
   342 HBufC* CAfStorage::SelectRowLC(TInt appId, const TDesC& actId) const
       
   343 {
       
   344     return BuildQueryLC(KSelectRow(),appId, actId);
       
   345 }
       
   346 
       
   347 // -----------------------------------------------------------------------------
       
   348 /**
       
   349  * Format query to select activities for application
       
   350  * @param appId - application id
       
   351  * @return formated sql query
       
   352  */
       
   353 HBufC* CAfStorage::SelectRowsLC(TInt appId) const
       
   354 {
       
   355     return BuildQueryLC(KSelectAppRows(), appId, KNullDesC);
       
   356 }
       
   357 
       
   358 // -----------------------------------------------------------------------------
       
   359 /**
       
   360  * Format query to delete activity
       
   361  * @param appId - application id
       
   362  * @param actId - activity id
       
   363  * @return formated sql query
       
   364  */
       
   365 HBufC* CAfStorage::DeleteRowLC(TInt appId, const TDesC& actId) const
       
   366 {
       
   367     return BuildQueryLC(KDeleteRow(),appId, actId);
       
   368 }
       
   369 
       
   370 // -----------------------------------------------------------------------------
       
   371 /**
       
   372  * Format query to delete activities for application
       
   373  * @param appId - application id
       
   374  * @return formated sql query
       
   375  */
       
   376 HBufC* CAfStorage::DeleteRowsLC(TInt appId) const
       
   377 {
       
   378     return BuildQueryLC(KDeleteRows(),appId, KNullDesC);
       
   379 }
       
   380 
       
   381 // -----------------------------------------------------------------------------
       
   382 /**
       
   383  * Format sql query
       
   384  * @format - sql format string
       
   385  * @param appId - application id
       
   386  * @param actId - activity id
       
   387  * @return formated sql query
       
   388  */
       
   389 HBufC* CAfStorage::BuildQueryLC(const TDesC& format,
       
   390                                       TInt appId,
       
   391                                       const TDesC& actId) const
       
   392 {
       
   393     TBuf<16> appName;
       
   394     appName.AppendNum(appId);
       
   395     RBuf actName;
       
   396     CleanupClosePushL(actName);
       
   397     actName.CreateL(actId.Length());
       
   398     actName.Copy(actId);
       
   399     HBufC* query = HBufC::NewL(format.Length() +
       
   400                                appName.Length() +
       
   401                                actName.Length() );
       
   402     query->Des().AppendFormat(format, &appName, &actName);
       
   403     CleanupStack::PopAndDestroy(&actName);
       
   404     CleanupStack::PushL(query);
       
   405     return query;
       
   406 }
       
   407 
       
   408 // -----------------------------------------------------------------------------
       
   409 /**
       
   410  * Execute sql query and result serialize into buffer
       
   411  * @param dst - destination result buffer
       
   412  * @param query - sql activity query
       
   413  */
       
   414 void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst, const TDesC& query, CAfEntry::AccessRights rights, TInt limit)
       
   415 {
       
   416     RDbView view;// Create a view on the database
       
   417     CleanupClosePushL(view);
       
   418     User::LeaveIfError(view.Prepare(mActDb, TDbQuery(query), view.EReadOnly));
       
   419     User::LeaveIfError(view.EvaluateAll());
       
   420     ActivitiesL(dst, view, rights, limit);
       
   421     CleanupStack::PopAndDestroy(&view);
       
   422 }
       
   423 
       
   424 // -----------------------------------------------------------------------------
       
   425 /**
       
   426  * Return view deserialisd into entries array
       
   427  * @param dst - destination result
       
   428  * @param query - view
       
   429  * @param rights - acess rights
       
   430  */
       
   431 void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst, RDbView& src, CAfEntry::AccessRights rights, TInt limit)
       
   432 {
       
   433     CDbColSet* row = src.ColSetL();
       
   434     CleanupStack::PushL(row);
       
   435 
       
   436     const TInt flagsOffset(row->ColNo(KFlagsColumnName)),
       
   437                applicationOffset(row->ColNo(KApplicationColumnName)),
       
   438                activityOffset(row->ColNo(KActivityColumnName)),
       
   439                dataOffset(row->ColNo(KDataColumnName));
       
   440 
       
   441     RBuf activityName;
       
   442     CleanupClosePushL(activityName);
       
   443 
       
   444     for (src.FirstL(); src.AtRow(); src.NextL()) {
       
   445         if(0 < limit && dst.Count() >= limit) {
       
   446             break;
       
   447         }
       
   448         src.GetL();
       
   449         ReadDataL(activityName, src, activityOffset);
       
   450 
       
   451         CAfEntry *entry = CAfEntry::NewLC(src.ColInt32(flagsOffset),
       
   452                                           src.ColInt64(applicationOffset),
       
   453                                           activityName,
       
   454                                           KNullDesC,
       
   455                                           KNullDesC8,
       
   456                                           KNullDesC8);
       
   457         if (CAfEntry::Public == rights && (entry->Flags() & CAfEntry::Invisible)) {
       
   458             CleanupStack::PopAndDestroy(entry);
       
   459             continue;
       
   460         }
       
   461         InternalizeDataL(*entry, src, dataOffset);
       
   462         
       
   463         if (CAfEntry::Public == rights || 0 >= limit) {
       
   464             entry->SetDataL(KNullDesC8(), CAfEntry::Private);
       
   465         }
       
   466         dst.AppendL(entry);
       
   467         CleanupStack::Pop(entry);
       
   468     }
       
   469 
       
   470     CleanupStack::PopAndDestroy(&activityName);
       
   471     CleanupStack::PopAndDestroy(row);
       
   472 }
       
   473 
       
   474 // -----------------------------------------------------------------------------
       
   475 /**
       
   476  * Get activity for update
       
   477  * @param query - destination query result
       
   478  * @param appId - application id
       
   479  * @param actId - activity id
       
   480  */
       
   481 void CAfStorage::GetActivityForUpdateL(RDbView& view, TInt appId, const TDesC& actId)
       
   482 {
       
   483     HBufC* query(SelectRowLC(appId, actId));
       
   484     User::LeaveIfError(view.Prepare(mActDb, TDbQuery(*query), view.EUpdatable));
       
   485     CleanupStack::PopAndDestroy(query);
       
   486     User::LeaveIfError(view.EvaluateAll());
       
   487     if (!view.FirstL()) {
       
   488         User::Leave(KErrNotFound);
       
   489     }
       
   490 }
       
   491 
       
   492 // -----------------------------------------------------------------------------
       
   493 void CAfStorage::ReadDataL(RBuf& dst, RDbRowSet& src, TInt offset) const
       
   494 {
       
   495     const TInt length(src.ColLength(offset));
       
   496     CAfEntry::ReallocL(dst, length);
       
   497     RDbColReadStream srcStream;
       
   498     srcStream.OpenLC(src,offset);
       
   499     srcStream.ReadL(dst, src.ColLength(offset));
       
   500     CleanupStack::PopAndDestroy(&srcStream);
       
   501 }
       
   502 
       
   503 // -----------------------------------------------------------------------------
       
   504 void CAfStorage::ExternalizeDataL(RDbRowSet& dst,const CAfEntry &src, TInt offset) const
       
   505 {
       
   506     RDbColWriteStream dbStream;
       
   507     CleanupClosePushL(dbStream);
       
   508     dbStream.OpenL(dst, offset);
       
   509     src.ExternalizeDataOnlyL(dbStream);
       
   510     CleanupStack::PopAndDestroy(&dbStream);
       
   511 }
       
   512 
       
   513 // -----------------------------------------------------------------------------
       
   514 void CAfStorage::InternalizeDataL(CAfEntry & dst, RDbRowSet& src, TInt offset) const
       
   515 {
       
   516     RDbColReadStream dbStream;
       
   517     CleanupClosePushL(dbStream);
       
   518     dbStream.OpenL(src, offset);
       
   519     dst.InternalizeDataOnlyL(dbStream);
       
   520     CleanupStack::PopAndDestroy(&dbStream);
       
   521 }
       
   522 
       
   523 // -----------------------------------------------------------------------------
       
   524 //
       
   525 // -----------------------------------------------------------------------------
       
   526 //
       
   527 void CAfStorage::StoragePathL(RBuf &dst, 
       
   528                   RFs& fileSystem, 
       
   529                   TBool persistent)
       
   530 {
       
   531     if (dst.MaxLength() < KMaxPathLength) {
       
   532         dst.ReAllocL(KMaxPathLength);
       
   533     } 
       
   534     dst.Zero();
       
   535     User::LeaveIfError(fileSystem.PrivatePath(dst));
       
   536     if(persistent) {
       
   537         dst.Append(KPersistent);
       
   538     }
       
   539     else {
       
   540         dst.Append(KNonPersistent);
       
   541     } 
       
   542 }
       
   543 
       
   544 // -----------------------------------------------------------------------------
       
   545 //
       
   546 // -----------------------------------------------------------------------------
       
   547 //
       
   548 void CAfStorage::AppStoragePathL(RBuf &dst, 
       
   549                      RFs& fileSystem,
       
   550                      TInt uid,
       
   551                      TBool persistent)
       
   552 {
       
   553     StoragePathL(dst, fileSystem, persistent);
       
   554     
       
   555     //Format activity path
       
   556     dst.AppendFormat( KUidFormat, uid); 
       
   557     }
       
   558 
       
   559 // -----------------------------------------------------------------------------
       
   560 //
       
   561 // -----------------------------------------------------------------------------
       
   562 //
       
   563 void CAfStorage::ThumbnailPathL(RBuf &dst, 
       
   564                                 RFs& fileSystem, 
       
   565                                 TInt uid, 
       
   566                                 const TDesC &activityName,
       
   567                                 TBool persistent)
       
   568 {
       
   569     RBuf8 buff8;
       
   570     CleanupClosePushL(buff8);
       
   571     buff8.CreateL(activityName.Length());
       
   572     buff8.Copy(activityName);
       
   573     HBufC8 *activityHash = Md5HexDigestL(buff8);
       
   574     CleanupStack::PopAndDestroy(&buff8);
       
   575     CleanupStack::PushL(activityHash);
       
   576     
       
   577     AppStoragePathL(dst, fileSystem, uid, persistent);
       
   578     
       
   579     RBuf hash16;
       
   580     CleanupClosePushL(hash16);
       
   581     hash16.CreateL(KMaxPathLength);
       
   582     hash16.Copy(*activityHash);
       
   583     dst.Append(hash16);//reuse already allocated buffer to convert 8 -> 16
       
   584     CleanupStack::PopAndDestroy(&hash16);
       
   585     dst.Append(KExtFormat());
       
   586     CleanupStack::PopAndDestroy(activityHash);
       
   587        
       
   588     BaflUtils::EnsurePathExistsL(fileSystem, dst);
       
   589 }
       
   590 
       
   591 // -----------------------------------------------------------------------------
       
   592 //
       
   593 // -----------------------------------------------------------------------------
       
   594 //
       
   595 HBufC8* CAfStorage::Md5HexDigestL(const TDesC8 &string)
       
   596 {
       
   597     _LIT8(KMd5HexFormat, "%+02x");
       
   598     CMD5* md5 = CMD5::NewL();
       
   599     CleanupStack::PushL(md5);
       
   600     
       
   601     TPtrC8 hashedSig(md5->Hash(string));
       
   602     
       
   603     HBufC8* buf = HBufC8::NewL(hashedSig.Length() * 2);
       
   604     TPtr8 bufPtr = buf->Des();
       
   605     
       
   606     for(TInt i(0); i< hashedSig.Length(); ++i) {
       
   607         bufPtr.AppendFormat(KMd5HexFormat,hashedSig[i]);
       
   608     }
       
   609     CleanupStack::PopAndDestroy(md5);
       
   610     return buf;
       
   611 }