--- /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