ncdengine/provider/storage/src/ncdstoragebase.cpp
changeset 0 ba25891c3a9e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/provider/storage/src/ncdstoragebase.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,840 @@
+/*
+* 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 "ncdstoragebase.h"
+
+#include <s32buf.h>
+
+#include "ncddatabasestorageimpl.h"
+#include "ncdstoragedataitem.h"
+#include "ncdstoragepanics.pan"
+#include "catalogsutils.h"
+
+#include "catalogsdebug.h"
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageBase::~CNcdStorageBase()
+    {
+    DLTRACEIN(( "" ));
+    delete iUid;
+    delete iStorageFolder;
+    delete iName;
+    iOpenItems.Reset();
+    iRemovedItems.Reset();
+    iItems.ResetAndDestroy();
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageBase::CNcdStorageBase( HBufC* aUid, HBufC* aStorageFolder, 
+        HBufC* aName ) :
+    iUid( aUid ),
+    iStorageFolder( aStorageFolder ),
+    iName( aName ),
+    iOpen( EFalse ),
+    iListener( NULL )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageBase* CNcdStorageBase::NewL(
+    RFs& aFs,
+    const TDesC& aUid,
+    const TDesC& aStorageFolder,
+    const TDesC& aStorageName )
+    {
+    DLTRACE( ( _L("Path: %S"), &aStorageFolder ) );
+    CNcdStorageBase* storage = 
+        storage = CNcdDatabaseStorage::NewL( 
+            aFs, aUid, aStorageFolder, 
+            aStorageName ); 
+
+    return storage;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdStorageBase::Uid() const
+    {
+    DASSERT( iUid );
+    DLTRACE( ( _L("Uid: %S"), iUid ) );
+    
+    return *iUid;
+    }
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdStorageBase::StorageFolder() const
+    {
+    DASSERT( iStorageFolder );
+    return *iStorageFolder;
+    }
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdStorageBase::Name() const
+    {
+    DASSERT( iName );
+    return *iName;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+TInt CNcdStorageBase::Open()
+    {
+    DLTRACEIN(("this: %x", this));
+    if( IsOpen() )
+        {
+        User::Panic( KNcdStoragePanic, ENcdStoragePanicAlreadyOpen );
+        }
+    
+    TRAPD( err, DoOpenL() );
+
+    if( err == KErrNone )
+        {
+        iOpen = ETrue;
+        }
+
+    return err;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::Close()
+    {
+    DLTRACEIN(("this: %x", this));
+    if( IsOpen() )
+        {
+        DoClose();
+        iOpen = EFalse;
+        }
+
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CNcdStorageBase::IsOpen() const
+    {
+    return iOpen;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageItem* CNcdStorageBase::StorageItemL( const TDesC& aUid, TInt aType )
+    {
+    DLTRACEIN( (_L("aUid: %S, aType: %d"), &aUid, aType ) );
+    DPROFILING_BEGIN( x );
+    CNcdStorageItem* item = FindStorageItem( aUid, aType );
+
+    if ( !item )
+        {
+        TRAPD( err,
+            {
+            // Create item
+            item = CreateStorageItemLC( aUid, aType );            
+
+            // Store item to array
+            iItems.InsertInAddressOrderL( item );
+            DLTRACE(("Items: %d", iItems.Count() ));
+            CleanupStack::Pop( item );
+            });
+
+        if( err == KErrNone )
+            {
+            iListener->CacheOpened();
+            TRAP( err, iListener->CacheReadyL() );
+            }
+
+        if( err != KErrNone )
+            {
+            if( !ItemsOpen() )
+                {
+                DoRollback();
+                }
+
+            User::Leave( err );
+            }
+        }
+
+    DPROFILING_END( x );
+    DLTRACEOUT((""));
+    return item;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::StorageItemsL( RPointerArray<MNcdStorageItem>& aItems )
+    {
+    RPointerArray<CNcdStorageItemIdentifier> items;
+    CleanupResetAndDestroyPushL( items );
+
+    // Get storage item identifiers from storage
+    GetAllItemsFromStorageL( items );
+
+    // Get storage items
+    TInt count = items.Count();
+    aItems.ReserveL( aItems.Count() + count );
+    
+    for( TInt i = 0; i < count; i++ )
+        {
+        aItems.AppendL( StorageItemL( items[i]->Id(), items[i]->Type() ) );
+        }
+
+    CleanupStack::PopAndDestroy( &items );    
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::RemoveItemsL( 
+    const RArray<RNcdDatabaseItems>& aDoNotRemoveItems )
+    {
+    DLTRACEIN((""));
+    DoRemoveItemsL( aDoNotRemoveItems );
+    
+    // reset arrays so that removed items are not left hanging aroung
+    iOpenItems.Reset();
+    iRemovedItems.Reset();
+    iItems.ResetAndDestroy();
+    }
+
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::OpenItemL( CNcdStorageItem* aItem )
+    {
+    DLTRACEIN(("this: %x", this));
+    iOpenItems.ReserveL( iOpenItems.Count() + 1 );
+
+    DoOpenItemL( aItem );
+
+    // Same item can't be opened multiple times (CNcdStorageItem::OpenL)
+    // so we don't have to worry about adding it many times to the open item
+    // array. Also we can't run out of memory because we already reserved 
+    // memory for the item so we can ignore the error
+    iOpenItems.InsertInAddressOrder( aItem );
+    
+    if( iListener && iOpenItems.Count() == 1 )
+        {
+        iListener->CacheOpened();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::SaveItemL( CNcdStorageItem* aItem )
+    {
+    DLTRACEIN(("this: %x", this));
+    TInt index = iOpenItems.FindInAddressOrder( aItem );
+
+    if( index < 0 )
+        {
+        User::Panic( KNcdStoragePanic, ENcdStoragePanicItemNotOpen );
+        }
+
+    iOpenItems.Remove( index );
+
+    if( iListener && iOpenItems.Count() == 0 )
+        {
+        iListener->CacheReadyL();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::RollbackItems()
+    {
+    DLTRACEIN((""));
+    Rollback();
+
+    iListener->NotifyRollback();
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+TInt CNcdStorageBase::Commit()
+    {
+    DLTRACEIN((""));
+    TInt err = DoCommit();
+
+    if( err == KErrNone )
+        {
+        TInt count = iRemovedItems.Count();
+        TInt index = 0;
+        for( TInt i = 0; i < count; i++ )
+            {
+            index = iItems.FindInAddressOrder( iRemovedItems[i] );
+            if( index >= 0 )
+                {
+                iItems.Remove( index );
+                }
+            DLTRACE(("Items: %d", iItems.Count() ));
+            delete iRemovedItems[i];
+            iRemovedItems[i] = NULL;
+            }
+        }
+
+    iRemovedItems.Reset();    
+    return err;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::RemoveItemL( CNcdStorageItem* aItem )
+    {
+    DLTRACEIN(("this: %x", this));
+    TInt insertError( iRemovedItems.InsertInAddressOrder( aItem ) );
+    if ( insertError == KErrAlreadyExists )
+        {
+        DLINFO(("Remove item was already in the array."));
+        return;
+        }
+    User::LeaveIfError( insertError );
+
+    TRAPD( err, DoRemoveItemL( aItem ) );
+
+    if( err != KErrNone )
+        {
+        TInt index = iRemovedItems.FindInAddressOrder( aItem );
+        if( index >= 0 )
+            {
+            iRemovedItems.Remove( index );
+            }
+        DLERROR(("Error: %d occurred when removing", err));
+        User::Leave( err );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::Rollback()
+    {
+    DoRollback();
+
+    TInt count = iOpenItems.Count();
+    for( TInt i = 0; i < count; i++ )
+        {
+        iOpenItems[i]->SetOpen( EFalse );
+        }
+
+    iOpenItems.Reset();
+    iRemovedItems.Reset();
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::ReadDataL( CNcdStorageItem* aItem, 
+    MNcdStorageDataItem& aDataItem )
+    {
+    DoReadDataL( aItem, aDataItem );
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::WriteDataL( CNcdStorageItem* aItem, 
+    MNcdStorageDataItem& aDataItem )
+    {
+    DoWriteDataL( aItem, aDataItem );
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CNcdStorageBase::ItemsOpen() const
+    {
+    DLTRACEIN(("this: %x, items open: %d", this, iOpenItems.Count() ));
+    return ( iOpenItems.Count() > 0 );
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+HBufC8* CNcdStorageBase::GetDataL( CNcdStorageItem* aItem )
+    {
+    return DoGetDataL( aItem );
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageItem* CNcdStorageBase::FindStorageItem( const TDesC& aUid, 
+    TInt aType )
+    {
+    TInt count = iItems.Count();
+    CNcdStorageItem* item = NULL;
+
+    for( TInt i = 0; i < count; i++ )
+        {
+        item = iItems[i];
+
+        if( item->Type() == aType && 
+            item->Uid().Compare( aUid ) == 0 )
+            {
+            return item;
+            }
+        }    
+        
+    return NULL;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageBase::SetListener( CNcdStorageBaseListener* aListener )
+    {
+    iListener = aListener;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CNcdStorageBase::ItemExistsInStorageL( const TDesC& aUid, TInt aType )
+    {
+    return ItemExistsL( aUid, aType );
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+HBufC8* CNcdStorageBase::GetAllDataLC( RReadStream& aStream )
+    {
+    MStreamBuf* streamBuf = aStream.Source();
+    TInt size = streamBuf->SizeL();
+
+    HBufC8* dataBuffer = HBufC8::NewLC( size );
+    TPtr8 data = dataBuffer->Des();
+
+    aStream.ReadL( data, size );
+
+    return dataBuffer;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+HBufC8* CNcdStorageBase::GetAllDataL( RReadStream& aStream )
+    {
+    HBufC8* dataBuffer = GetAllDataLC( aStream );
+    CleanupStack::Pop( dataBuffer );    
+    return dataBuffer;
+    }
+
+
+
+// ********************************
+//         CNcdStorageItem
+// ********************************
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageItem* CNcdStorageItem::NewL( CNcdStorageBase* aStorage, 
+    const TDesC& aUid, TInt aType )
+    {
+    CNcdStorageItem* item = new (ELeave) CNcdStorageItem( aStorage );
+    CleanupStack::PushL( item );
+    item->ConstructL( aUid, aType );
+    CleanupStack::Pop( item );
+    return item;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageItem::~CNcdStorageItem()
+    {
+    DLTRACEIN((""));
+    delete iIdentifier;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageItem::CNcdStorageItem( CNcdStorageBase* aStorage ) :
+    iStorage( aStorage ),
+    iOpen( EFalse )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageItem::ConstructL( const TDesC& aUid, TInt aType  )
+    {
+    DLTRACEIN(("this: %x", this));
+    iIdentifier = CNcdStorageItemIdentifier::NewL( aUid, aType );
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageItem::SetOpen( TBool aOpen )
+    {
+    iOpen = aOpen;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CNcdStorageItem::IsOpen() const
+    {
+    return iOpen;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdStorageItem::Uid() const
+    {
+    return iIdentifier->Id();
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+TInt CNcdStorageItem::Type() const
+    {
+    return iIdentifier->Type();
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageItem::OpenL()
+    {
+    DLTRACEIN(("this: %x", this));
+    if( iOpen )
+        {
+        User::Panic( KNcdStoragePanic, ENcdStoragePanicItemAlreadyOpen );
+        }
+
+    iStorage->OpenItemL( this );
+    iOpen = ETrue;
+    DLTRACEOUT(("Opened %x", this));
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageItem::SaveL()
+    {
+    DLTRACEIN(("this: %x", this));
+    if( !iOpen )
+        {
+        User::Panic( KNcdStoragePanic, ENcdStoragePanicItemNotOpen );
+        }
+
+    TRAPD( err, iStorage->SaveItemL( this ) );
+    if( err != KErrNone )
+        {
+        Rollback();
+        User::Leave( err );
+        }
+    iOpen = EFalse;
+    DLTRACEOUT(("closed: %x", this));
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageItem::Rollback()
+    {
+    DLTRACEIN(("this: %x", this));
+    if( iOpen )
+        {
+        iOpen = EFalse;
+        iStorage->RollbackItems();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageItem::RemoveFromStorageL()
+    {
+    DLTRACEIN(("this: %x", this));
+    if( iOpen )
+        {
+        User::Panic( KNcdStoragePanic, ENcdStoragePanicItemAlreadyOpen );
+        }
+
+    iStorage->RemoveItemL( this );
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageItem::SetDataItem( MNcdStorageDataItem* aDataItem )
+    {
+    iDataItem = aDataItem;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageItem::ReadDataL()
+    {
+    iStorage->ReadDataL( this, *iDataItem );
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageItem::WriteDataL()
+    {
+    DLTRACEIN(("this: %x", this));
+    if( iOpen )
+        {
+        TRAPD( err, iStorage->WriteDataL( this, *iDataItem ) );
+        if ( err != KErrNone ) 
+            {
+            Rollback();
+            User::Leave( err );
+            }
+        }
+    else
+        {
+        User::Panic( KNcdStoragePanic, ENcdStoragePanicItemNotOpen );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+HBufC8* CNcdStorageItem::GetDataLC()
+    {
+    HBufC8* data = iStorage->GetDataL( this );
+    CleanupStack::PushL( data );
+    return data;
+    }
+
+
+// ********************************
+//     CNcdStorageItemIdentifier
+// ********************************
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageItemIdentifier* CNcdStorageItemIdentifier::NewLC( 
+    const TDesC8& aId, TInt aType )
+    {
+    CNcdStorageItemIdentifier* identifier = new (ELeave) 
+        CNcdStorageItemIdentifier( aType );
+    CleanupStack::PushL( identifier );
+    identifier->ConstructL( aId );
+    return identifier;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageItemIdentifier* CNcdStorageItemIdentifier::NewL( 
+    const TDesC16& aId, TInt aType )
+    {
+    CNcdStorageItemIdentifier* identifier = 
+        CNcdStorageItemIdentifier::NewLC( aId, aType );
+    CleanupStack::Pop( identifier );
+    return identifier;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageItemIdentifier* CNcdStorageItemIdentifier::NewLC( 
+    const TDesC16& aId, TInt aType )
+    {
+    CNcdStorageItemIdentifier* identifier = new (ELeave) 
+        CNcdStorageItemIdentifier( aType );
+    CleanupStack::PushL( identifier );
+    identifier->ConstructL( aId );
+    return identifier;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageItemIdentifier::CNcdStorageItemIdentifier( TInt aType ) :
+    iType( aType )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CNcdStorageItemIdentifier::~CNcdStorageItemIdentifier()
+    {
+    delete iId;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdStorageItemIdentifier::Id() const
+    {
+    return *iId;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+TInt CNcdStorageItemIdentifier::Type() const
+    {
+    return iType;
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageItemIdentifier::ConstructL( const TDesC16& aId )
+    {
+    iId = aId.AllocL();
+    }
+
+
+void CNcdStorageItemIdentifier::ConstructL( const TDesC8& aId )
+    {  
+    TInt length = aId.Length();
+
+    if( length % 2 != 0 )
+      {
+      User::Panic( KNcdStoragePanic, ENcdStoragePanicIdDescAlign );
+      }
+
+    iId = HBufC16::NewL( length / 2 );
+    iId->Des().Copy( (const TUint16*)aId.Ptr(), length / 2 );
+    }