mpx/commonframework/common/src/mpxmediadataarray.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:55:47 +0200
changeset 0 a2952bb97e68
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* 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 "mpxmediadataarray.h"
#include "mpxheapmanager.h"
#include "mpxdata.h"

#define ITEM(x,y) RMPXHeapManager::Ptr<RMPXMediaDataItem>(x,y)

// -----------------------------------------------------------------------------
// RMPXMediaDataItemArray::Append
// -----------------------------------------------------------------------------
//
TInt RMPXMediaDataItemArray::Append(
    TUint aClientHandle,
    const TMPXAttribute& aAttr,
    TMPXAttributeType aAttrType,
    const TDesC8& aData)
    {
    MPX_ASSERT(aClientHandle);
    //
    TInt r=KErrNone;
    RMPXMediaDataItem* item=NewItem(aClientHandle,aAttr,aAttrType,aData);
    if (item)
        {
        RMPXDataItemArray::Append(aClientHandle,*item);
        }
    else
        {
        r=KErrNoMemory;
        }
    return r;
    }


// -----------------------------------------------------------------------------
// RMPXMediaDataItemArray::Set
// -----------------------------------------------------------------------------
//
TInt RMPXMediaDataItemArray::Set(
    TUint aClientHandle,
    const TMPXAttribute& aAttr,
    TMPXAttributeType aAttrType,
    const TDesC8& aData,
    TInt aIndex)
    {
    TInt r=KErrNone;
    RMPXMediaDataItem* item=NewItem(aClientHandle,aAttr,aAttrType,aData);
    if (item)
        {       
        RMPXDataItemArray::Set(aClientHandle,*item,aIndex);
        }
    else
        {
        r=KErrNoMemory;
        }
    return r;
    }

// -----------------------------------------------------------------------------
// RMPXMediaDataItemArray::RMPXMediaDataItemArray
// -----------------------------------------------------------------------------
//
TInt RMPXMediaDataItemArray::Insert(
    TUint aClientHandle,
    const TMPXAttribute& aAttr,
    TMPXAttributeType aAttrType,
    const TDesC8& aData,
    TInt aIndex)
    {
    TInt r=KErrNone;
    RMPXMediaDataItem* item=NewItem(aClientHandle,aAttr,aAttrType,aData);
    if (item)
        {       
        RMPXDataItemArray::Insert(aClientHandle,*item,aIndex);
        }
    else
        {
        r=KErrNoMemory;
        }
    return r;
    }

// -----------------------------------------------------------------------------
// RMPXMediaDataItemArray::Index
// -----------------------------------------------------------------------------
//
TInt RMPXMediaDataItemArray::Index(TUint aClientHandle,const TMPXAttribute& aAttr)
    {
    TInt index( KErrNotFound );
    RMPXMediaDataItem* item=NULL;
    
    if (iFirstItemOffset)
        {
        item=ITEM(aClientHandle,iFirstItemOffset);
        while(item)
            {
            index++;
            if (item->Attribute()==aAttr)
                {
                //
                // Found it, so break outer of the loop, but first store
                // the current position in case an index based query will
                // follow (e,g, for data, type etc.)
                //
                iIndex=index;
                iPos=RMPXHeapManager::Offset(aClientHandle,item);
                break;
                }
            TInt next=item->NextOffset();
            item=next?ITEM(aClientHandle,next):NULL;
            }
        }
    return item?index:KErrNotFound;
    }
 
 // -----------------------------------------------------------------------------
// RMPXMediaDataItemArray::NewItem
// -----------------------------------------------------------------------------
//   
 RMPXMediaDataItem* RMPXMediaDataItemArray::NewItem(
    TUint aClientHandle,
    const TMPXAttribute& aAttr,
    TMPXAttributeType aAttrType,
    const TDesC8& aData)
    {
    MPX_ASSERT(aClientHandle);
    //
    RMPXHeapManager& m=RMPXHeapManager::HeapManager(aClientHandle);
    TAny* ptr=m.Alloc(aClientHandle, sizeof(RMPXMediaDataItem) + aData.Size());
    RMPXMediaDataItem* item(NULL);
    if (ptr) 
        { 
        //Alloc media data item
        item = new(ptr)RMPXMediaDataItem();
        //Copy data to RMPXMediaDataItem
        item->Copy(aClientHandle,aData);
        item->SetAttribute(aAttr,aAttrType);
        }
    return item;
    }

// -----------------------------------------------------------------------------
// RMPXDataItemArray::Copy
// -----------------------------------------------------------------------------
//
TInt RMPXMediaDataItemArray::Copy(
    TUint aClientHandle,
    const RMPXMediaDataItemArray& aArray)
    {
    Reset(aClientHandle); // Clear existing data
    TInt r=KErrNone;
    TInt first=aArray.iFirstItemOffset;
    if (first)
        {
        RMPXMediaDataItem* item=ITEM(aClientHandle,first);
        while(item)
            {
            MMPXData* d=MMPXData::Data(aClientHandle,
                                       item->Buf(aClientHandle),
                                       item->Size());
            if (d)
                { 
                // It's a global object. e.g. media or media array, so we need to copy
                // that and place the handle into the buffer
                //
                MMPXData* newd=NULL;
                TRAP(r,newd=MMPXData::NewL(aClientHandle,*d)); // will end up recursive
                if (r==KErrNone)
                    {
                    // Create the data: a buffer of 8 bytes
                    //
                    const TInt KMediaStreamLen=sizeof(MMPXData::TMPXObjectType)+sizeof(TUint);
                    TBuf8<KMediaStreamLen> newbuf;
                    //
                    TUint* ptr=(TUint*)newbuf.Ptr(); // pointer to the new (empty) buffer
                    TUint* oldPtr=(TUint*)item->Buf(aClientHandle); // pointer to the old data
                    //
                    *ptr=*oldPtr; // the TMPXObjectType
                    *++ptr=newd->DataHandle(aClientHandle); //  the data: handle to this new data
                    //
                    newbuf.SetLength(KMediaStreamLen);
                    //
                    r=Append(aClientHandle,item->Attribute(),item->Type(),newbuf);
                    //
                    // Don't need to call newd->Release(aClientHandle) currently, since the Append()
                    // would have created a ref count of 1, and the MMPXData::NewL() doesn't.
                    //
                    }
                }
            else 
                {
                // Regular streamed object, so we can duplicate it by just copying the bytes
                // in an Append()
                //
                r=Append(aClientHandle,item->Attribute(),item->Type(),item->Data(aClientHandle));
                }
            item=item->NextOffset()&&r==KErrNone?ITEM(aClientHandle,item->NextOffset()):NULL;
            }
        }
    return r;
    }

// End of file