IMPSengine/datautils/src/impspacked.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:41:52 +0200
changeset 0 094583676ce7
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2002 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: 
* package entry and entity class.
*
*/


// INCLUDE FILES
#include    <s32std.h>
#include    "impsfields.h"
#include    "impspacked.h"
#include    "impsutils.h"

// MACROS
#ifndef _DEBUG
#define _NO_IMPS_LOGGING_
#endif
// ================= MEMBER FUNCTIONS =======================


// ---------------------------------------------------------
// TImpsPackedEntity::TImpsPackedEntity
// ---------------------------------------------------------
//
EXPORT_C TImpsPackedEntity::TImpsPackedEntity( HBufC8*& aBuffer )
: iBuffer( aBuffer )
    {}

// ---------------------------------------------------------
// TImpsPackedEntity::PackEntity
// ---------------------------------------------------------
//
EXPORT_C TInt TImpsPackedEntity::PackEntity( const CImpsFields& aEntity )
    {
#ifndef _NO_IMPS_LOGGING_
    CImpsClientLogger::Log(_L("TImpsPackedEntity::PackEntityL begins"));
#endif
    // find the start and end of the buffer
    const TUint8* pS = iBuffer->Ptr();
    const TUint8* pE = PtrAdd( pS, iBuffer->Des().MaxSize() );

    TInt error = DoPackEntity( pS, pE, aEntity );
    if ( error==KErrNone )
        {
        // update the length of the buffer
        iBuffer->Des().SetLength( pS-iBuffer->Ptr() );
        }

#ifndef _NO_IMPS_LOGGING_
    CImpsClientLogger::Log(_L("TImpsPackedEntity::PackEntityL ends with %d"), error);
#endif
    return error;
    }

// ---------------------------------------------------------
// TImpsPackedEntity::UnpackEntityL
// ---------------------------------------------------------
//
EXPORT_C void TImpsPackedEntity::UnpackEntityL( CImpsFields& aEntity )
    {
#ifndef _NO_IMPS_LOGGING_
    CImpsClientLogger::Log(_L("TImpsPackedEntity::UnPackEntityL begins"));
#endif

    TUint8* pS = CONST_CAST(TUint8*, iBuffer->Ptr());
    DoUnpackEntityL( pS, aEntity );

#ifndef _NO_IMPS_LOGGING_
    CImpsClientLogger::Log(_L("TImpsPackedEntity::UnPackEntityL ends"));
#endif
    }

// ---------------------------------------------------------
// TImpsPackedEntity::DoUnpackEntityL
// ---------------------------------------------------------
void TImpsPackedEntity::DoUnpackEntityL( 
    TUint8*& aPtr, 
    CImpsFields& aEntity )
    {
    TInt sizePackedCont = Align4( KImpsPackedCopyData );
    
    // Get the entry from the start of the buffer
    Mem::Copy( &aEntity, aPtr, sizePackedCont);
    aPtr = aPtr + sizePackedCont;

    CImpsData* data = aEntity.Data( );
    DoUnpackDataL( aPtr, *data );
    }



// ---------------------------------------------------------
// TImpsPackedEntity::DoUnpackDataL
// ---------------------------------------------------------
void TImpsPackedEntity::DoUnpackDataL(
    TUint8*& aPtr, 
    CImpsData& aEntity )
    {
    TInt mySize = 0;
    Mem::Copy( &mySize, aPtr, sizeof( mySize ) );
    aPtr += sizeof( mySize );
    aEntity.UnPackL( aPtr );
    }

// ---------------------------------------------------------
// TImpsPackedEntity::DoPackEntity
// Format is
//   fundamental types copied 
//   plus each descriptor: size + 8-bit data
// NOTICE: This must be modified always when CImpsFields members is changed!!!
// ---------------------------------------------------------
TInt TImpsPackedEntity::DoPackEntity(
    const TUint8*& aPtrStart, 
    const TUint8* aPtrEnd, 
    const CImpsFields& aEntity )
//
// Fails with KErrOverflow if the packed entry is too large
// aPtrStart is always returned pointing to the end of the packed entry (even if too large)
//
    {
    // make sure the entry can fit into the memory area defined by the two pointers

    TInt size =  aEntity.Size();
    if ( ( aPtrStart + size ) > aPtrEnd )
        {
        aPtrStart += size;
        return KErrOverflow;
        }

    size = Align4( KImpsPackedCopyData );
    // copy the entry and descriptors into the memory area
    Mem::Copy((void*)aPtrStart, &aEntity, size );
    aPtrStart += size;

    // Notice: Login data is not packed at the very moment

    TInt ret = DoPackData( aPtrStart, aPtrEnd, *aEntity.Data( ) );

    return ret;
    }



// ---------------------------------------------------------
// TImpsPackedEntity::DoPackData
// ---------------------------------------------------------
TInt TImpsPackedEntity::DoPackData(
    const TUint8*& aPtrStart, 
    const TUint8* aPtrEnd, 
    const CImpsData& aEntity )
    {
    TInt size = aEntity.Size(); 
    size += (2 * sizeof (TInt));		//size,count
    if ( ( aPtrStart + size ) > aPtrEnd )
        {
        aPtrStart += size;
        return KErrOverflow;
        }
    // write the size first.
    Mem::Copy( (void*)aPtrStart, &size, sizeof( size ) );
    aPtrStart = aPtrStart + sizeof( size );

    TInt ret = aEntity.Pack( aPtrStart );
    return ret;
    }

// ---------------------------------------------------------
// TImpsPackedEntity::DoPackDescriptor
// ---------------------------------------------------------
void TImpsPackedEntity::DoPackDescriptor(
    const TUint8*& aPtrStart, 
    const TDesC& /*HBufC* */ aDescriptor )
    {

    TInt32 tempSize = 0;
    tempSize = aDescriptor.Size();
    Mem::Copy( (void*)aPtrStart, &tempSize, sizeof( tempSize) );
    aPtrStart = aPtrStart + sizeof( tempSize );
    if ( tempSize )
        {
        Mem::Copy( (void*)aPtrStart, aDescriptor.Ptr(), tempSize);
        aPtrStart = aPtrStart + tempSize ;
        }
    }

// ---------------------------------------------------------
// TImpsPackedEntity::DoUnpackDescriptorLC
// ---------------------------------------------------------
void TImpsPackedEntity::DoUnpackDescriptorLC(
    const TUint8*& aPtrStart, 
    HBufC*& aDescriptor )
    {

    const TUint8* textPtr = aPtrStart;
    TInt32 tempSize = 0;

    Mem::Copy( &tempSize, textPtr, sizeof( tempSize) );
    textPtr = textPtr + sizeof( tempSize );
    if ( tempSize > 0 )
        {
        // put and leave this to the CleanupStack because of other the
        // calling method can leave
        aDescriptor = HBufC::NewL( tempSize / 2 );  
        CleanupStack::PushL( aDescriptor );
        Mem::Copy( (void*)aDescriptor->Ptr(), textPtr, tempSize );
        aDescriptor->Des().SetLength( tempSize / 2 ); 
        textPtr = textPtr + tempSize; 
        }
    else
        {
        aDescriptor = NULL;
        }
    if ( tempSize < 0 )
        {
#ifndef _NO_IMPS_LOGGING_
    CImpsClientLogger::Log(_L("TImpsPackedEntity: Descriptor Length 0"));
#endif
        }

    aPtrStart = (TUint8*) textPtr;
    
    }

// ---------------------------------------------------------
// TImpsPackedEntity::DoPackArray
// ---------------------------------------------------------
EXPORT_C void TImpsPackedEntity::DoPackArray(
            const TUint8*& aPtrStart,
            const MDesCArray* aArray )
    {

    // First count nbr of elements
    TInt32 nbrElements = 0;

    if ( aArray != NULL )
        {
        nbrElements = aArray->MdcaCount();
        }
    Mem::Copy( (void*)aPtrStart, &nbrElements, sizeof( nbrElements ) );
    aPtrStart = aPtrStart + sizeof( nbrElements );

    // Store each array element
    for ( TInt i = 0; i < nbrElements; i++ )
        {
        TPtrC element = aArray->MdcaPoint(i);
        DoPackDescriptor( aPtrStart, element );
        }

    }

// ---------------------------------------------------------
// TImpsPackedEntity::DoUnpackArrayL
// ---------------------------------------------------------
EXPORT_C void TImpsPackedEntity::DoUnpackArrayL(
            const TUint8*& aPtrStart,
            CDesCArray* aArray )
    {

    const TUint8* textPtr = aPtrStart;
    TInt32 tempSize = 0;

    // Get the number of elements
    Mem::Copy( &tempSize, textPtr, sizeof( tempSize) );
    textPtr = textPtr + sizeof( tempSize );

    if ( tempSize == 0 )
        {
        // There are no elements in array
        aPtrStart = (TUint8*) textPtr;
        return;
        }

    // Unpack each element and add to the array
    HBufC* myPtr;
    HBufC*& descriptor = myPtr;
    for (  TInt i = 0; i < tempSize; i++ )
        {
        // This allocates memory for each element
        DoUnpackDescriptorLC( textPtr, descriptor );  
        // Array may contain zero length descriptor
        if ( descriptor != NULL )
            {
            aArray->AppendL( descriptor->Des() );
            //delete myPtr;
            CleanupStack::PopAndDestroy();
            }
        else
            {
            aArray->AppendL( KNullDesC );
            }
        myPtr = NULL;
        }

    // Increase the packed data pointer
    aPtrStart = (TUint8*) textPtr;
    }


// ================= OTHER EXPORTED FUNCTIONS ==============

//  End of File