diff -r 000000000000 -r ba25891c3a9e ncdengine/provider/storage/src/ncdstorageclientimpl.cpp --- /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 + +#include "ncdstorageclientimpl.h" + +#include +#include +#include +#include + +#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( 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( 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; + } +