mpx/commonframework/common/src/mpxdataarray.cpp
changeset 0 a2952bb97e68
child 12 51035f0751c2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpx/commonframework/common/src/mpxdataarray.cpp	Thu Dec 17 08:55:47 2009 +0200
@@ -0,0 +1,408 @@
+/*
+* 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:  Implementation of array of variable size elements on global chunk
+*
+*/
+
+#include <mpxlog.h>
+#include "mpxdataarray.h"
+#include "mpxheapmanager.h"
+#include "mpxdata.h"
+
+
+#define ITEM(x,y) RMPXHeapManager::Ptr<RMPXDataItem>(x,y)
+#define OFFSET(x,y) RMPXHeapManager::Offset(x,y)
+
+// -----------------------------------------------------------------------------
+// RMPXDataItem::Reset
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItem::Reset(TUint aClientHandle)
+    {
+    MPX_ASSERT(aClientHandle);
+    if (iBufLen)
+        {
+        // If the buffer contains a media/media array, then we need
+        // to release its reference (could end up being recursive)
+        //
+        TAny* data=Buf(aClientHandle);
+        MMPXData* d=MMPXData::Data(aClientHandle,data,iBufLen);
+        if(d)
+            {
+            d->Release(aClientHandle);
+            }
+        // Now free the actual buffer
+        RMPXHeapManager& m=RMPXHeapManager::HeapManager(aClientHandle);
+        iUid=0;
+        iBufLen=0;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItem::Copy
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItem::Copy(TUint aClientHandle,TAny* aSrc,TInt aSize)
+    {
+    MPX_ASSERT(aSrc&&aClientHandle);
+    //
+    Reset(aClientHandle);
+    RMPXHeapManager& m=RMPXHeapManager::HeapManager(aClientHandle);
+    //Set uid for this item
+    iUid=m.IncrementCounter();
+    if (aSize) // Could be zero sized, e.g. zero-length descriptor
+        {
+        (void)Mem::Copy((TAny*)((TUint8*)this+iBufOffset),aSrc,aSize);
+        iBufLen=aSize;
+        //
+        // Need to increment ref count if adding a 'sleeping' media/media array object
+        //
+        TAny* data=Buf(aClientHandle);
+        MMPXData* d=MMPXData::Data(aClientHandle,data,iBufLen);
+        if(d)
+            {
+            d->AddRef(aClientHandle);
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItem::Data
+// -----------------------------------------------------------------------------
+//
+TAny* RMPXDataItem::Buf(TUint aClientHandle)
+    {
+    ASSERT(aClientHandle);
+    return iBufLen?(TAny*)((TUint8*)this+iBufOffset):NULL;
+    }
+    
+// -----------------------------------------------------------------------------
+// RMPXDataItem::Insert
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItem::Insert(
+    TUint aClientHandle,
+    RMPXDataItem* aPrevious,
+    RMPXDataItem* aNext)
+    {
+    MPX_ASSERT(aClientHandle);
+    //
+    iPreviousOffset=aPrevious?OFFSET(aClientHandle,aPrevious):0;
+    iNextOffset=aNext?OFFSET(aClientHandle,aNext):0;
+    TInt thisOffset=OFFSET(aClientHandle,this);
+    if (aPrevious)
+        {
+        aPrevious->iNextOffset=thisOffset;
+        }
+    if (aNext)
+        {
+        aNext->iPreviousOffset=thisOffset;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItem::Insert
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItem::Insert(
+    TUint aClientHandle,
+    TInt aPreviousOffset,
+    TInt aNextOffset)
+    {
+    MPX_ASSERT(aClientHandle);
+    iPreviousOffset=aPreviousOffset;
+    iNextOffset=aNextOffset;
+    TInt thisOffset=OFFSET(aClientHandle,this);
+    if (aPreviousOffset)
+        {
+        RMPXDataItem* previous=ITEM(aClientHandle,aPreviousOffset);
+        previous->iNextOffset=thisOffset;
+        }
+    if (aNextOffset)
+        {
+        RMPXDataItem* next=ITEM(aClientHandle,aNextOffset);
+        next->iPreviousOffset=thisOffset;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItem::Set
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItem::Set(TUint aClientHandle,RMPXDataItem* aOldItem)
+    {
+    MPX_ASSERT(aOldItem&&aClientHandle);
+    //
+    iPreviousOffset=aOldItem->iPreviousOffset;
+    iNextOffset=aOldItem->iNextOffset;
+    TInt thisOffset=OFFSET(aClientHandle,this);
+    if (iPreviousOffset)
+        {
+        RMPXDataItem* previous=ITEM(aClientHandle,iPreviousOffset);
+        previous->iNextOffset=thisOffset;
+        }
+    if (iNextOffset)
+        {
+        RMPXDataItem* next=ITEM(aClientHandle,iNextOffset);
+        next->iPreviousOffset=thisOffset;
+        }
+    
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItem::Set
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItem::Set(TUint aClientHandle,TInt aOldItemOffset)
+    {
+    RMPXDataItem* oldItem=ITEM(aClientHandle,aOldItemOffset);
+    Set(aClientHandle,oldItem);
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItem::Remove
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItem::Remove(TUint aClientHandle)
+    {
+    MPX_ASSERT(aClientHandle);
+    if (iPreviousOffset)
+        {
+        RMPXDataItem* previous=ITEM(aClientHandle,iPreviousOffset);
+        previous->iNextOffset=iNextOffset;
+        }
+    if (iNextOffset)
+        {
+        RMPXDataItem* next=ITEM(aClientHandle,iNextOffset);
+        next->iPreviousOffset=iPreviousOffset;
+        }
+    iPreviousOffset=0;
+    iNextOffset=0;
+    }
+
+
+// -----------------------------------------------------------------------------
+// RMPXDataItemArray::RMPXDataItemArray
+// -----------------------------------------------------------------------------
+//
+RMPXDataItemArray::RMPXDataItemArray()
+    : iFirstItemOffset(0),iLastItemOffset(0),iNumItems(0),iPos(0),iIndex(0)
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItemArray::Close
+// -----------------------------------------------------------------------------
+//    
+void RMPXDataItemArray::Close(TUint aClientHandle)
+    { 
+    MPX_ASSERT(aClientHandle); 
+    Reset(aClientHandle);
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItemArray::DataItem
+// -----------------------------------------------------------------------------
+//
+RMPXDataItem* RMPXDataItemArray::DataItem(TUint aClientHandle,TInt aIndex)
+    {
+    MPX_ASSERT(aClientHandle&&aIndex>=0&&aIndex<iNumItems);
+    //
+    RMPXDataItem* dataItem=NULL;
+    while(!dataItem)
+        {
+        //
+        // Start looking from the current position: this is an optimisation
+        // since the client is likely to either iterate from this position,
+        // or make another query from this item. iPos and iIndex MUST 
+        // correspond
+        //
+        RMPXDataItem* item=ITEM(aClientHandle,iPos);
+        if (iIndex==aIndex)
+            {
+            dataItem=item;
+            }
+        else if (iIndex>aIndex)
+            {
+            iIndex--;
+            iPos=item->PreviousOffset();
+            }
+        else // if (iIndex<aIndex)
+            {
+            iIndex++;
+            iPos=item->NextOffset();
+            }
+        }
+    MPX_ASSERT(dataItem && (TInt)dataItem > (TInt)&RMPXHeapManager::HeapManager(aClientHandle));
+    return dataItem;
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItemArray::Delete
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItemArray::Delete(TUint aClientHandle,RMPXDataItem* aItem)
+    {
+    MPX_ASSERT(aClientHandle&&aItem);
+    aItem->Close(aClientHandle);  // Release objects in the buffer
+    TInt r=RMPXHeapManager::HeapManager(aClientHandle).Free(aClientHandle,aItem);
+    MPX_ASSERT(r==KErrNone);
+    (void)r;
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItemArray::Append
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItemArray::Append(TUint aClientHandle,RMPXDataItem& aItem)
+    {
+    MPX_ASSERT(aClientHandle);
+    //
+    aItem.Insert(aClientHandle,iLastItemOffset,0);
+    iLastItemOffset=OFFSET(aClientHandle,&aItem);
+    if (iNumItems++==0)
+        {
+        iFirstItemOffset=iLastItemOffset;
+        }
+    iPos=iFirstItemOffset;
+    iIndex=0;
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItemArray::Set
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItemArray::Set(TUint aClientHandle,RMPXDataItem& aItem,TInt aIndex)
+    {
+    MPX_ASSERT(aClientHandle&&aIndex>=0&&aIndex<iNumItems);
+    //
+    RMPXDataItem* oldItem=DataItem(aClientHandle,aIndex);
+    aItem.Set(aClientHandle,oldItem);
+    TInt oldItemOffset=OFFSET(aClientHandle,oldItem); 
+    TInt itemOffset=OFFSET(aClientHandle,&aItem); 
+    if (oldItemOffset==iLastItemOffset) 
+        {
+        iLastItemOffset=itemOffset;
+        }
+     if (oldItemOffset==iFirstItemOffset) 
+        {
+        iFirstItemOffset=itemOffset;
+        } 
+    Delete(aClientHandle,oldItem);
+    iPos=iFirstItemOffset;
+    iIndex=0;
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItemArray::Insert
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItemArray::Insert(TUint aClientHandle,RMPXDataItem& aItem,TInt aIndex)
+    {
+    MPX_ASSERT(aClientHandle&&aIndex>=0&&aIndex<iNumItems);
+    //
+    RMPXDataItem* itemBefore=aIndex==0?NULL:DataItem(aClientHandle,aIndex-1);
+    RMPXDataItem* itemAfter=aIndex<iNumItems?DataItem(aClientHandle,aIndex):NULL;
+    aItem.Insert(aClientHandle,itemBefore,itemAfter);
+    TInt itemOffset=OFFSET(aClientHandle,&aItem);
+    if (!itemAfter) // this is the last one
+        {
+        iLastItemOffset=itemOffset;
+        }
+    if (!itemBefore||iNumItems==0)  // this is the first or the only one
+        {
+        iFirstItemOffset=itemOffset;
+        } 
+    iPos=iFirstItemOffset;
+    iIndex=0;
+    ++iNumItems;
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItemArray::Remove
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItemArray::Remove(TUint aClientHandle,TInt aIndex)
+    {
+    MPX_ASSERT(aClientHandle&&aIndex>=0&&aIndex<iNumItems);
+    //
+    RMPXDataItem* item=DataItem(aClientHandle,aIndex);
+    TInt itemOffset=OFFSET(aClientHandle,item);
+    if (iFirstItemOffset==itemOffset)
+        {
+        iFirstItemOffset=item->NextOffset();
+        }
+    if (iLastItemOffset==itemOffset)
+        {
+        iLastItemOffset=item->PreviousOffset();
+        }   
+    item->Remove(aClientHandle);
+    Delete(aClientHandle,item);
+    iPos=iFirstItemOffset; 
+    iIndex=0; 
+    --iNumItems;
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItemArray::Reset
+// -----------------------------------------------------------------------------
+//
+void RMPXDataItemArray::Reset(TUint aClientHandle)
+    {
+    if (iFirstItemOffset)
+        {
+        RMPXDataItem* item=ITEM(aClientHandle,iFirstItemOffset);
+        while(item)
+            {
+            Delete(aClientHandle,item);
+            item=item->NextOffset()?ITEM(aClientHandle,item->NextOffset()):NULL;
+            }
+        }
+    // Reset members
+    iFirstItemOffset=0;
+    iLastItemOffset=0;
+    iNumItems=0;
+    iPos=0;
+    iIndex=0; 
+    }
+
+// -----------------------------------------------------------------------------
+// RMPXDataItemArray::Find
+// -----------------------------------------------------------------------------
+//
+TInt RMPXDataItemArray::Find(TUint aClientHandle,const RMPXDataItem& aItem)
+    {
+    TInt r=KErrNotFound;
+    if (iFirstItemOffset)
+        {
+        TInt index=KErrNotFound;
+        RMPXDataItem* item=ITEM(aClientHandle,iFirstItemOffset);
+        while(item)
+            {  
+            index++;
+            TUint8* d1 = reinterpret_cast<TUint8*>(item->Buf(aClientHandle));
+            TUint8* d2 = 
+             reinterpret_cast<TUint8*>(const_cast<RMPXDataItem*>(&aItem)->
+                                                            Buf(aClientHandle));
+            if (Mem::Compare(d1, item->Size(), d2, aItem.Size()) == 0)
+                {
+                r=index;
+                break;
+                }
+            item=item->NextOffset()?ITEM(aClientHandle,item->NextOffset()):NULL;
+            }
+        }  
+    return r;
+    }
+// End of file