mtpfws/mtpfw/datatypes/src/tmtptypeflatbase.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:11:40 +0200
changeset 0 d0791faffa3f
permissions -rw-r--r--
Revision: 201003 Kit: 201005

// Copyright (c) 2006-2009 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:
//

/**
 @file
 @publishedPartner
*/

#include <mtp/mtpdatatypeconstants.h>
#include <mtp/mtptypessimple.h>
#include <mtp/tmtptypeflatbase.h>

#include "mtpdatatypespanic.h"

/**
Default constructor.
*/
EXPORT_C TMTPTypeFlatBase::TMTPTypeFlatBase() :
    iBuffer(NULL, 0, 0)
    {
    
    }
    
/**
Resets the dataset by zero filling it..
*/
EXPORT_C void TMTPTypeFlatBase::Reset()
    {
    iBuffer.FillZ();
    } 
    
/**
Provides a copy of the specified element.
@param aElementId The identifier of the requested element.
@param aElement The MMTPType target data buffer.
@leave One of the system wide error code, if a processing error occurs. 
@panic MTPDataTypes 3, if the target buffer type does not match the requested 
element.
*/
EXPORT_C void TMTPTypeFlatBase::GetL(TInt aElementId, MMTPType& aElement) const
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == aElement.Type()), Panic(EMTPTypeIdMismatch));
    
    TBool commit(aElement.CommitRequired());
    TBool complete(EFalse);
    TPtr8 dest(NULL, 0);
    TInt offset(info.iOffset);
    
    TInt err(aElement.FirstWriteChunk(dest));
    while (((err == KMTPChunkSequenceCompletion) || (err == KErrNone)) && (!complete))
        {
        complete = (err == KMTPChunkSequenceCompletion);
        
        TPtrC8 src(&(iBuffer[offset]), (info.iSize - (offset - info.iOffset)));  
        dest.Copy(src);
        offset += dest.Length();
        
        if (commit)
            {
            aElement.CommitChunkL(dest);   
            }
        
        if (!complete)
            {
            err = aElement.NextWriteChunk(dest);                
            }  
        }
        
    if (err != KMTPChunkSequenceCompletion)
        {
        User::Leave(err);            
        }
    }

/**
Updates the specified element.
@param aElementId The identifier of the element to update.
@param aElement The MMTPType source data buffer.
@leave One of the system wide error code, if a processing error occurs. 
@panic MTPDataTypes 3, if the source buffer type does not match the requested 
element.
@panic MTPDataTypes 4, if the source buffer size does not match the requested 
element.
*/  
EXPORT_C void TMTPTypeFlatBase::SetL(TInt aElementId, const MMTPType& aElement)
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == aElement.Type()), Panic(EMTPTypeIdMismatch));
    __ASSERT_ALWAYS((info.iSize == aElement.Size()), Panic(EMTPTypeSizeMismatch));
    
    TBool complete(EFalse);
    TInt offset(info.iOffset);
    TPtrC8 src;
    
    TInt err(aElement.FirstReadChunk(src));
    while (((err == KMTPChunkSequenceCompletion) || (err == KErrNone)) && (!complete))
        {
        __ASSERT_ALWAYS((((offset + src.Length()) - info.iOffset) <= info.iSize), Panic(EMTPTypeSizeMismatch));
        complete = (err == KMTPChunkSequenceCompletion);
        
        iBuffer.Replace(offset, src.Length(), src);
        offset += src.Length();
        
        if (!complete)
            {
            err = aElement.NextReadChunk(src);                
            } 
        }
        
    if (err != KMTPChunkSequenceCompletion)
        {
        User::Leave(err);            
        }
    }
    
/**
Updates the specified element.
@param aElementId The identifier of the element to update.
@param aElement The source data.
@panic MTPDataTypes 3, if the source data type does not match the requested 
element.
*/    
EXPORT_C void TMTPTypeFlatBase::SetInt8(TInt aElementId, TInt8 aData)
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeINT8), Panic(EMTPTypeIdMismatch));
        
    TPtrC8 data(reinterpret_cast<TUint8*>(&aData), sizeof(aData));
    iBuffer.Replace(info.iOffset, data.Length(), data);
    }
    
/**
Updates the specified element.
@param aElementId The identifier of the element to update.
@param aElement The source data.
@panic MTPDataTypes 3, if the source data type does not match the requested 
element.
*/    
EXPORT_C void TMTPTypeFlatBase::SetInt16(TInt aElementId, TInt16 aData)
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeINT16), Panic(EMTPTypeIdMismatch));
        
    TPtrC8 data(reinterpret_cast<TUint8*>(&aData), sizeof(aData));
    iBuffer.Replace(info.iOffset, data.Length(), data);
    }
    
/**
Updates the specified element.
@param aElementId The identifier of the element to update.
@param aElement The source data.
@panic MTPDataTypes 3, if the source data type does not match the requested 
element.
*/    
EXPORT_C void TMTPTypeFlatBase::SetInt32(TInt aElementId, TInt32 aData)
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeINT32), Panic(EMTPTypeIdMismatch));
        
    TPtrC8 data(reinterpret_cast<TUint8*>(&aData), sizeof(aData));
    iBuffer.Replace(info.iOffset, data.Length(), data);
    }
    
/**
Updates the specified element.
@param aElementId The identifier of the element to update.
@param aElement The source data.
@panic MTPDataTypes 3, if the source data type does not match the requested 
element.
*/    
EXPORT_C void TMTPTypeFlatBase::SetInt64(TInt aElementId, TInt64 aData)
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeINT64), Panic(EMTPTypeIdMismatch));
        
    TPtrC8 data(reinterpret_cast<TUint8*>(&aData), sizeof(aData));
    iBuffer.Replace(info.iOffset, data.Length(), data);
    }
    
/**
Updates the specified element.
@param aElementId The identifier of the element to update.
@param aElement The source data.
@panic MTPDataTypes 3, if the source data type does not match the requested 
element.
*/    
EXPORT_C void TMTPTypeFlatBase::SetUint8(TInt aElementId, TUint8 aData)
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeUINT8), Panic(EMTPTypeIdMismatch));
        
    TPtrC8 data(reinterpret_cast<TUint8*>(&aData), sizeof(aData));
    iBuffer.Replace(info.iOffset, data.Length(), data);
    }
    
/**
Updates the specified element.
@param aElementId The identifier of the element to update.
@param aElement The source data.
@panic MTPDataTypes 3, if the source data type does not match the requested 
element.
*/    
EXPORT_C void TMTPTypeFlatBase::SetUint16(TInt aElementId, TUint16 aData)
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeUINT16), Panic(EMTPTypeIdMismatch));
        
    TPtrC8 data(reinterpret_cast<TUint8*>(&aData), sizeof(aData));
    iBuffer.Replace(info.iOffset, data.Length(), data);
    }
    
/**
Updates the specified element.
@param aElementId The identifier of the element to update.
@param aElement The source data.
@panic MTPDataTypes 3, if the source data type does not match the requested 
element.
*/    
EXPORT_C void TMTPTypeFlatBase::SetUint32(TInt aElementId, TUint32 aData)
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeUINT32), Panic(EMTPTypeIdMismatch));
        
    TPtrC8 data(reinterpret_cast<TUint8*>(&aData), sizeof(aData));
    iBuffer.Replace(info.iOffset, data.Length(), data);
    }
    
/**
Updates the specified element.
@param aElementId The identifier of the element to update.
@param aElement The source data.
@panic MTPDataTypes 3, if the source data type does not match the requested 
element.
*/    
EXPORT_C void TMTPTypeFlatBase::SetUint64(TInt aElementId, TUint64 aData)
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeUINT64), Panic(EMTPTypeIdMismatch));
        
    TPtrC8 data(reinterpret_cast<TUint8*>(&aData), sizeof(aData));
    iBuffer.Replace(info.iOffset, data.Length(), data);
    }

/**
Provides the value of the specified element.
@param aElementId The identifier of the requested element.
@return The value of the element.
@panic MTPDataTypes 3, if the source buffer type does not match the requested 
element.
*/
EXPORT_C TInt8 TMTPTypeFlatBase::Int8(TInt aElementId) const
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeINT8), Panic(EMTPTypeIdMismatch));
    return (static_cast<TInt8>(iBuffer[info.iOffset]));
    }

/**
Provides the value of the specified element.
@param aElementId The identifier of the requested element.
@return The value of the element.
@panic MTPDataTypes 3, if the source buffer type does not match the requested 
element.
*/
EXPORT_C TInt16 TMTPTypeFlatBase::Int16(TInt aElementId) const
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeINT16), Panic(EMTPTypeIdMismatch));
        
    // memcpy the element data to avoid alignment errors.
    TInt16 ret;
    memcpy(&ret, &iBuffer[info.iOffset], sizeof(ret));
    return ret;
    }

/**
Provides the value of the specified element.
@param aElementId The identifier of the requested element.
@return The value of the element.
@panic MTPDataTypes 3, if the source buffer type does not match the requested 
element.
*/
EXPORT_C TInt32 TMTPTypeFlatBase::Int32(TInt aElementId) const
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeINT32), Panic(EMTPTypeIdMismatch));
    
    // memcpy the element data to avoid alignment errors.
    TInt32 ret;
    memcpy(&ret, &iBuffer[info.iOffset], sizeof(ret));
    return ret;
    }

/**
Provides the value of the specified element.
@param aElementId The identifier of the requested element.
@return The value of the element.
@panic MTPDataTypes 3, if the source buffer type does not match the requested 
element.
*/
EXPORT_C TInt64 TMTPTypeFlatBase::Int64(TInt aElementId) const
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeINT64), Panic(EMTPTypeIdMismatch));
    
    // memcpy the element data to avoid alignment errors.
    TInt64 ret;
    memcpy(&ret, &iBuffer[info.iOffset], sizeof(ret));
    return ret;
    }

/**
Provides the value of the specified element.
@param aElementId The identifier of the requested element.
@return The value of the element.
@panic MTPDataTypes 3, if the source buffer type does not match the requested 
element.
*/
EXPORT_C TUint8 TMTPTypeFlatBase::Uint8(TInt aElementId) const
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeUINT8), Panic(EMTPTypeIdMismatch));
    return (static_cast<TUint8>(iBuffer[info.iOffset]));
    }

/**
Provides the value of the specified element.
@param aElementId The identifier of the requested element.
@return The value of the element.
@panic MTPDataTypes 3, if the source buffer type does not match the requested 
element.
*/
EXPORT_C TUint16 TMTPTypeFlatBase::Uint16(TInt aElementId) const
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeUINT16), Panic(EMTPTypeIdMismatch));
    
    // memcpy the element data to avoid alignment errors.
    TUint16 ret;
    memcpy(&ret, &iBuffer[info.iOffset], sizeof(ret));
    return ret;
    }

/**
Provides the value of the specified element.
@param aElementId The identifier of the requested element.
@return The value of the element.
@panic MTPDataTypes 3, if the source buffer type does not match the requested 
element.
*/
EXPORT_C TUint32 TMTPTypeFlatBase::Uint32(TInt aElementId) const
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeUINT32), Panic(EMTPTypeIdMismatch));
    
    // memcpy the element data to avoid alignment errors.
    TUint32 ret;
    memcpy(&ret, &iBuffer[info.iOffset], sizeof(ret));
    return ret;
    }

/**
Provides the value of the specified element.
@param aElementId The identifier of the requested element.
@return The value of the element.
@panic MTPDataTypes 3, if the source buffer type does not match the requested 
element.
*/
EXPORT_C TUint64 TMTPTypeFlatBase::Uint64(TInt aElementId) const
    {
    const TElementInfo& info(ElementInfo(aElementId));
    __ASSERT_ALWAYS((info.iType == EMTPTypeUINT64), Panic(EMTPTypeIdMismatch));
    
    // memcpy the element data to avoid alignment errors.
    TUint64 ret;
    memcpy(&ret, &iBuffer[info.iOffset], sizeof(ret));
    return ret;
    }
    
EXPORT_C TInt TMTPTypeFlatBase::FirstReadChunk(TPtrC8& aChunk) const
    {
    __ASSERT_ALWAYS(iBuffer.MaxLength() > 0, Panic(EMTPTypeBadStorage));
    aChunk.Set(iBuffer);
    return KMTPChunkSequenceCompletion;
    }
    
EXPORT_C TInt TMTPTypeFlatBase::NextReadChunk(TPtrC8& aChunk) const
    {
    aChunk.Set(NULL, 0);
    return KErrNotReady;
    }
    
EXPORT_C TInt TMTPTypeFlatBase::FirstWriteChunk(TPtr8& aChunk)
    {
    __ASSERT_ALWAYS(iBuffer.MaxLength() > 0, Panic(EMTPTypeBadStorage));
    aChunk.Set(&iBuffer[0], 0, iBuffer.MaxLength());
    return KMTPChunkSequenceCompletion;
    }
    
EXPORT_C TInt TMTPTypeFlatBase::NextWriteChunk(TPtr8& aChunk)
    {
    aChunk.Set(NULL, 0, 0);
    return KErrNotReady;
    }
    
EXPORT_C TUint64 TMTPTypeFlatBase::Size() const
    {
    return iBuffer.Size();
    }

EXPORT_C TUint TMTPTypeFlatBase::Type() const
    {
    return EMTPTypeFlat;        
    }

/**
Sets the MTP dataset buffer to be managed.
@param aBuffer The MTP dataset buffer to be managed.
*/
EXPORT_C void TMTPTypeFlatBase::SetBuffer(const TDes8& aBuffer)
    {
    iBuffer.Set(aBuffer.MidTPtr(0));
    iBuffer.SetLength(iBuffer.MaxLength());
    }