--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/provider/storage/src/ncdstorageclientimpl.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,464 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <bamdesca.h>
+
+#include "ncdstorageclientimpl.h"
+
+#include <f32file.h>
+#include <bautils.h>
+#include <badesca.h>
+#include <s32file.h>
+
+#include "ncdstorageimpl.h"
+#include "ncdstoragemanagerimpl.h"
+#include "catalogsconstants.h"
+#include "catalogsutils.h"
+
+#include "catalogsdebug.h"
+
+
+_LIT( KNamespaceFile, "namespaces" );
+
+// ======== MEMBER FUNCTIONS ========
+
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageClient::ConstructL( const TDesC& aUid )
+ {
+ DLTRACEIN( ("") );
+ // Copy the uid
+ iUid.CreateL( aUid );
+
+ RBuf path;
+ CleanupClosePushL( path );
+ path.CreateL( KMaxPath );
+
+ // Create the path string for the storage
+ AppendRoot( path );
+
+ // Create the directory
+ BaflUtils::EnsurePathExistsL( iOwner.FileSession(), path );
+
+ // Create storages for each found directory
+ //CreateStoragesFromFileSystemL( path );
+ CleanupStack::PopAndDestroy( &path );
+
+ // Read namespaces and create storages
+ TRAPD( err, ReadNamespacesL() );
+ if ( err != KErrNone && err != KErrNotFound )
+ {
+ User::Leave( err );
+ }
+ DLTRACEOUT( ("") );
+ }
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CNcdStorageClient* CNcdStorageClient::NewL( MNcdStorageOwner& aOwner,
+ const TDesC& aUid )
+ {
+ CNcdStorageClient* self = CNcdStorageClient::NewLC( aOwner, aUid );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// NewLC
+// ---------------------------------------------------------------------------
+//
+CNcdStorageClient* CNcdStorageClient::NewLC( MNcdStorageOwner& aOwner,
+ const TDesC& aUid )
+ {
+ CNcdStorageClient* self = new( ELeave ) CNcdStorageClient( aOwner );
+ CleanupStack::PushL( self );
+ self->ConstructL( aUid );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CNcdStorageClient::~CNcdStorageClient()
+ {
+ iUid.Close();
+ iStorages.ResetAndDestroy();
+ }
+
+
+// ---------------------------------------------------------------------------
+// Storage creator
+// ---------------------------------------------------------------------------
+//
+MNcdStorage& CNcdStorageClient::CreateStorageL( const TDesC& aNamespace )
+ {
+ DLTRACEIN( ("") );
+
+ TInt index = FindStorageByNamespace( aNamespace );
+
+ if ( index != KErrNotFound )
+ {
+ return *( iStorages[ index ] );
+ }
+
+ CNcdStorage* storage = CNcdStorage::NewLC( *this, aNamespace );
+ iStorages.AppendL( storage );
+ CleanupStack::Pop( storage );
+
+ // Save namespaces
+ SaveNamespacesL();
+ return *static_cast<MNcdStorage*>( storage );
+ }
+
+
+// ---------------------------------------------------------------------------
+// Storage getter
+// ---------------------------------------------------------------------------
+//
+MNcdStorage& CNcdStorageClient::StorageL( const TDesC& aNamespace )
+ {
+ DLTRACEIN(( _L("NS: %S"), &aNamespace ));
+ TInt index = FindStorageByNamespace( aNamespace );
+ User::LeaveIfError( index );
+ DLTRACEOUT(("index: %d", index));
+ return *(iStorages[index]);
+ }
+
+
+// ---------------------------------------------------------------------------
+// Storage remover
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageClient::RemoveStorageL( const TDesC& aNamespace )
+ {
+ DLTRACEIN((""));
+ if ( !aNamespace.Length() )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ TInt index = FindStorageByNamespace( aNamespace );
+
+ if ( index == KErrNotFound )
+ {
+ DLTRACEOUT(("Namespace not found"));
+ return;
+ }
+
+ // Generate path before deleting the storage in case aNamespace is a
+ // reference to storage's member variable
+ RBuf path;
+ CleanupClosePushL( path );
+ path.CreateL( KMaxPath );
+
+ // Generate path to the storage directory
+
+ AppendRoot( path );
+ path.Append( iStorages[ index ]->Directory() );
+ path.Append( KDirectorySeparator );
+
+
+ delete iStorages[ index ];
+ iStorages.Remove( index );
+
+
+ DLTRACE( ( _L("Deleting: %S"), &path ) );
+
+ CNcdStorageManager::RemoveDirectoryL( FileSession(),
+ path );
+
+ CleanupStack::PopAndDestroy( &path );
+
+ // Updates the list of namespaces
+ SaveNamespacesL();
+ DLTRACEOUT( ("") );
+ }
+
+
+// ---------------------------------------------------------------------------
+// Path generator
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageClient::AppendRoot( TDes& aDes ) const
+ {
+ DLTRACEIN((""));
+
+ iOwner.AppendRoot( aDes );
+ aDes.Append( iUid );
+ aDes.Append( KDirectorySeparator );
+
+ DLTRACEOUT((""));
+ }
+
+// ---------------------------------------------------------------------------
+// File session getter
+// ---------------------------------------------------------------------------
+//
+RFs& CNcdStorageClient::FileSession()
+ {
+ DLTRACEIN((""));
+ return iOwner.FileSession();
+ }
+
+
+// ---------------------------------------------------------------------------
+// File manager getter
+// ---------------------------------------------------------------------------
+//
+CFileMan& CNcdStorageClient::FileManager()
+ {
+ return iOwner.FileManager();
+ }
+
+// ---------------------------------------------------------------------------
+// Client UID getter
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdStorageClient::ClientUid() const
+ {
+ return iUid;
+ }
+
+
+// ---------------------------------------------------------------------------
+// NamespacesL
+// ---------------------------------------------------------------------------
+//
+MDesCArray* CNcdStorageClient::NamespacesLC() const
+ {
+ DLTRACEIN((""));
+ CPtrCArray* array = new(ELeave) CPtrCArray( KListGranularity );
+
+ // Casting ensures that the popped pointer matches the returned pointer
+ CleanupDeletePushL( static_cast<MDesCArray*>( array) );
+ array->SetReserveL( iStorages.Count() );
+
+ for ( TInt i = 0; i < iStorages.Count(); ++i )
+ {
+ array->AppendL( iStorages[i]->Namespace() );
+ }
+
+ return array;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CNcdStorageClient::CNcdStorageClient( MNcdStorageOwner& aOwner ) :
+ iOwner( aOwner )
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// Searches for a storage that matches the given namespace
+// ---------------------------------------------------------------------------
+//
+TInt CNcdStorageClient::FindStorageByNamespace(
+ const TDesC& aNamespace ) const
+ {
+ TInt count = iStorages.Count();
+ for ( TInt i = 0; i < count; ++i )
+ {
+ if ( iStorages[ i ]->Namespace().Compare( aNamespace ) == 0)
+ {
+ return i;
+ }
+ }
+
+ return KErrNotFound;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Creates a storage object for each found directory
+// ---------------------------------------------------------------------------
+//
+/*
+void CNcdStorageClient::CreateStoragesFromFileSystemL( const TDesC& aPath )
+ {
+ DLTRACEIN((""));
+ CDir* dirList = NULL;
+ CDir* fileList = NULL;
+ User::LeaveIfError( FileSession().GetDir( aPath,
+ KEntryAttNormal, ESortByName, fileList, dirList ) );
+ DLTRACE(("Creating storages"));
+ TInt err = KErrNone;
+
+ // No need for this
+ delete fileList;
+
+ CleanupStack::PushL( dirList );
+
+ for ( TInt i = 0; i < dirList->Count(); ++i )
+ {
+ TRAP( err, CreateStorageL( (*dirList)[i].iName ) );
+ if ( err != KErrNone && err != KErrAlreadyExists )
+ {
+ User::Leave( err );
+ }
+ }
+ CleanupStack::PopAndDestroy( dirList );
+ }
+*/
+
+// ---------------------------------------------------------------------------
+// Reads namespace encodings from the namespace file
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageClient::ReadNamespacesL()
+ {
+ DLTRACEIN((""));
+ RBuf filename;
+ CleanupClosePushL( filename );
+ filename.CreateL( KMaxPath );
+
+ AppendRoot( filename );
+ filename.Append( KNamespaceFile );
+
+ HBufC8* data = ReadFileL( FileSession(), filename );
+ CleanupStack::PopAndDestroy( &filename );
+
+ CleanupStack::PushL( data );
+ RDesReadStream reader( *data );
+ CleanupClosePushL( reader );
+
+ // number of namespaces
+ TInt32 count = reader.ReadInt32L();
+
+ iStorages.ReserveL( count );
+
+ HBufC* namesp = NULL;
+ HBufC* dir = NULL;
+ DLINFO(("Internalizing %d namespaces"));
+ while ( count )
+ {
+ DLTRACE(("Internalizing namespace and directory"));
+ InternalizeDesL( namesp, reader );
+ CleanupStack::PushL( namesp );
+
+ InternalizeDesL( dir, reader );
+ CleanupStack::PushL( dir );
+
+ TBool exists = DirectoryExistsL( *dir );
+ if ( exists )
+ {
+ DLTRACE(( _L("Client nsp: %S in dir: %S"),
+ namesp, dir ));
+
+ // Ownership of the namesp and dir is transferred
+ CNcdStorage* client = CNcdStorage::NewL(
+ *this, namesp, dir );
+ CleanupStack::Pop( 2, namesp ); // dir, namesp
+
+ // Won't fail because of the ReserveL-call
+ iStorages.Append( client );
+ DLTRACE(("Client created successfully"));
+ }
+ else
+ {
+ DLTRACE(("Client doesn't exist anymore"));
+ CleanupStack::PopAndDestroy( 2, namesp ); // dir, namesp
+ }
+ namesp = NULL;
+ dir = NULL;
+ --count;
+ }
+ CleanupStack::PopAndDestroy( 2, data ); // reader, data
+ }
+
+// ---------------------------------------------------------------------------
+// Save namespaces
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageClient::SaveNamespacesL()
+ {
+ DLTRACEIN((""));
+ TFileName tempName;
+
+ // Get root dir
+ RBuf target;
+ CleanupClosePushL( target );
+ target.CreateL( KMaxPath );
+ AppendRoot( target );
+
+ DLINFO(( "Creating file write stream.." ));
+ RFileWriteStream writer;
+ CleanupClosePushL( writer );
+
+ DLINFO(( "Getting file session.." ));
+ RFs& fs( FileSession() );
+ // Create a temp file
+ User::LeaveIfError( writer.Temp(
+ fs,
+ target,
+ tempName,
+ EFileWrite | EFileStream ) );
+
+ writer.WriteInt32L( iStorages.Count() );
+ for ( TInt i = 0; i < iStorages.Count(); ++i )
+ {
+ ExternalizeDesL( iStorages[i]->Namespace(), writer );
+ ExternalizeDesL( iStorages[i]->Directory(), writer );
+ }
+ // Commit explicitly so we can react to errors
+ writer.CommitL();
+ CleanupStack::PopAndDestroy( &writer );
+
+ // Append the namespace-file to root dir
+ target.Append( KNamespaceFile );
+
+ // Replace the old file with the new one
+ BaflUtils::DeleteFile( fs, target );
+ User::LeaveIfError( fs.Rename( tempName, target ) );
+
+ CleanupStack::PopAndDestroy( &target ); // target
+ DLTRACEOUT(("File saved successfully"));
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// Checks if the directory exists
+// ---------------------------------------------------------------------------
+//
+TBool CNcdStorageClient::DirectoryExistsL( const TDesC& aDir )
+ {
+ DLTRACEIN(( _L("Directory: %S"), &aDir ));
+ RBuf path;
+ CleanupClosePushL( path );
+ path.CreateL( KMaxPath );
+ AppendRoot( path );
+ path.Append( aDir );
+
+ TBool exists = BaflUtils::FolderExists( FileSession(), path );
+ CleanupStack::PopAndDestroy( &path );
+ return exists;
+ }
+