wvsettings20/IMPSSrc/CIMPSSAPKeyValuePair.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) 2004 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:  Key - value container.
*
*/

// INCLUDE FILES
#include	<utf.h> // for unicode character conversions
#include	<centralrepository.h>
#include    "e32std.h"
#include    "CIMPSSAPKeyValuePair.h"
#include	"IMPSSAPSettingsStoreDefinitions.h"
#include	"IMPSSAPSettingsStorePanics.h"

//MACROS

//Helper macro to check value type in data set
#define REQUIRE_SET_VALUE_TYPE( aType ) \
        { \
        TBool _settable = ( iValueType == EValueTypeNone ) || \
                          ( iValueType == aType ); \
        if( !_settable )\
            {\
            return KErrGeneral;\
            }\
        } \
     
//Helper macro to check value type in data get
#define REQUIRE_GET_VALUE_TYPE( aType ) \
        { \
        if( iValueType == EValueTypeNone ) \
            { \
            return KErrNotFound; \
            } \
        TBool _readable = ( iValueType == aType ); \
        if( !_readable ) \
            { \
            return KErrGeneral; \
            } \
        } \
     

// ================= MEMBER FUNCTIONS =======================

// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::New()
// -----------------------------------------------------------------------------
//
CIMPSSAPKeyValuePair* CIMPSSAPKeyValuePair::New( const TDesC16& aKey )
    {
    //Non leaving two phased constructor!!!

    CIMPSSAPKeyValuePair* self = new CIMPSSAPKeyValuePair;	// CSI: 62 #
    if ( self )
        {
        self->iKey = aKey.Alloc();
        if ( !self->iKey )
            {
            delete self;
            self = NULL;
            }
        }

    return self;
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::NewLC()
// -----------------------------------------------------------------------------
//
CIMPSSAPKeyValuePair* CIMPSSAPKeyValuePair::NewLC( RReadStream& aStream )
    {
    CIMPSSAPKeyValuePair* self = new ( ELeave ) CIMPSSAPKeyValuePair;
    CleanupStack::PushL( self );
    self->ConstructL( aStream );
    return self;
    }

// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::NewLC()
// -----------------------------------------------------------------------------
//
CIMPSSAPKeyValuePair* CIMPSSAPKeyValuePair::NewLC( const TDesC& aKeyValuePairFlat )
    {
    CIMPSSAPKeyValuePair* self = new ( ELeave ) CIMPSSAPKeyValuePair;
    CleanupStack::PushL( self );
    self->ParseFlatKeyValuePairL( aKeyValuePairFlat );
    return self;
    }

// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::~CIMPSSAPKeyValuePair()
// Destructor
// -----------------------------------------------------------------------------
//
CIMPSSAPKeyValuePair::~CIMPSSAPKeyValuePair()
    {
    Reset();
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::CIMPSSAPKeyValuePair()
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CIMPSSAPKeyValuePair::CIMPSSAPKeyValuePair()
        : iValueType( EValueTypeNone )
    {
    }



// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::ConstructL()
// -----------------------------------------------------------------------------
//
void CIMPSSAPKeyValuePair::ConstructL( RReadStream& aStream )
    {
    //Note! This implementation must be in sync with
    //ExternalizeL()

    //Extension space
    aStream.ReadInt32L();

    //Default data
    TInt keyLength = aStream.ReadInt32L();
    iKey = HBufC::NewL( keyLength );
    TPtr keyPtr( iKey->Des() );
    aStream.ReadL( keyPtr, keyLength );

    iValueType = static_cast< TValueType > ( aStream.ReadInt8L() );
    switch ( iValueType )
        {
        case EValueTypeInt:
            {
            iInt = aStream.ReadInt32L();
            break;
            }

        case EValueTypeDesC8:
            {
            TInt descLength = aStream.ReadInt32L();
            iBuf8 = HBufC8::NewL( descLength );
            TPtr8 descPtr8( iBuf8->Des() );
            aStream.ReadL( descPtr8, descLength );
            break;
            }


        case EValueTypeDesC16:
            {
            TInt descLength = aStream.ReadInt32L();
            iBuf16 = HBufC16::NewL( descLength );
            TPtr16 descPtr16( iBuf16->Des() );
            aStream.ReadL( descPtr16, descLength );
            break;
            }

        //FLOW THROUGH
        case EValueTypeNone:
        default:
            {
            break;
            }
        };
    }



// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::Reset()
// -----------------------------------------------------------------------------
//
void CIMPSSAPKeyValuePair::Reset()
    {
    switch ( iValueType )
        {
        case EValueTypeDesC8:
            {
            delete iBuf8;
            iBuf8 = NULL;
            break;
            }


        case EValueTypeDesC16:
            {
            delete iBuf16;
            iBuf16 = NULL;
            break;
            }

        //FLOW THROUGH
        case EValueTypeInt:
        case EValueTypeNone:
        default:
            {
            break;
            }
        };

    iValueType = EValueTypeNone;

    delete iKey;
    iKey = NULL;
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::SetValue()
// -----------------------------------------------------------------------------
//
TInt CIMPSSAPKeyValuePair::SetValue( TInt aValue )
    {
    REQUIRE_SET_VALUE_TYPE( EValueTypeInt )

    TInt oldValue( iInt );
    iInt = aValue;
    iValueType = EValueTypeInt;

    TBool dataTooBig( IsDataTooBig() );
    TInt err( KErrNone );
    if ( dataTooBig )
        {
        iInt = oldValue;
        err = KErrTooBig;
        }
    __ASSERT_DEBUG( !err, Panic( EIMPSInvalidKeyValue ) );
    return err;
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::Key()
// -----------------------------------------------------------------------------
//
const TDesC& CIMPSSAPKeyValuePair::Key() const
    {
    return *iKey;
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::SetValue()
// -----------------------------------------------------------------------------
//
TInt CIMPSSAPKeyValuePair::SetValue( const TDesC8& aValue )
    {
    REQUIRE_SET_VALUE_TYPE( EValueTypeDesC8 )

    // Allocate memory for the new value
    HBufC8* tmp = aValue.Alloc();
    if ( !tmp )
        {
        return KErrNoMemory;
        }

    // Swap pointers
    HBufC8* tmp2( NULL );
    tmp2 = iBuf8;
    iBuf8 = tmp;
    iValueType = EValueTypeDesC8;

    TBool dataTooBig( IsDataTooBig() );
    TInt err( KErrNone );

    // Rollback if data too bog
    if ( dataTooBig )
        {
        iBuf8 = tmp2;
        delete tmp;
        err = KErrTooBig;
        }
    // Otherwise delete the old value
    else
        {
        delete tmp2;
        }


    __ASSERT_DEBUG( !err, Panic( EIMPSInvalidKeyValue ) );
    return err;
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::SetValue()
// -----------------------------------------------------------------------------
//
TInt CIMPSSAPKeyValuePair::SetValue( const TDesC16& aValue )
    {
    REQUIRE_SET_VALUE_TYPE( EValueTypeDesC16 )

    // Allocate memory for the new value
    HBufC16* tmp = aValue.Alloc();
    if ( !tmp )
        {
        return KErrNoMemory;
        }

    // Swap pointers
    HBufC16* tmp2( NULL );
    tmp2 = iBuf16;
    iBuf16 = tmp;
    iValueType = EValueTypeDesC16;

    TBool dataTooBig( IsDataTooBig() );
    TInt err( KErrNone );

    // Rollback if data too bog
    if ( dataTooBig )
        {
        iBuf16 = tmp2;
        delete tmp;
        err = KErrTooBig;
        }
    // Otherwise delete the old value
    else
        {
        delete tmp2;
        }

    __ASSERT_DEBUG( !err, Panic( EIMPSInvalidKeyValue ) );
    return err;
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::GetValue()
// -----------------------------------------------------------------------------
//
TInt CIMPSSAPKeyValuePair::GetValue( TInt& aValue ) const
    {
    REQUIRE_GET_VALUE_TYPE( EValueTypeInt )

    aValue = iInt;
    return KErrNone;
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::GetValue()
// -----------------------------------------------------------------------------
//
TInt CIMPSSAPKeyValuePair::GetValue( TPtrC8& aValue ) const
    {
    REQUIRE_GET_VALUE_TYPE( EValueTypeDesC8 )

    aValue.Set( *iBuf8 );
    return KErrNone;
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::GetValue()
// -----------------------------------------------------------------------------
//
TInt CIMPSSAPKeyValuePair::GetValue( TPtrC16& aValue ) const
    {
    REQUIRE_GET_VALUE_TYPE( EValueTypeDesC16 )

    aValue.Set( *iBuf16 );
    return KErrNone;
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::ExternalizeL()
// -----------------------------------------------------------------------------
//
void CIMPSSAPKeyValuePair::ExternalizeL( RWriteStream& aStream ) const
    {
    //Extension space
    aStream.WriteInt32L( 0 );

    //Default data
    aStream.WriteInt32L( iKey->Length() );
    aStream.WriteL( *iKey );
    aStream.WriteInt8L( iValueType );

    switch ( iValueType )
        {
        case EValueTypeInt:
            {
            aStream.WriteInt32L( iInt );
            break;
            }

        case EValueTypeDesC8:
            {
            aStream.WriteInt32L( iBuf8->Length() );
            aStream.WriteL( *iBuf8 );
            break;
            }


        case EValueTypeDesC16:
            {
            aStream.WriteInt32L( iBuf16->Length() );
            aStream.WriteL( *iBuf16 );
            break;
            }

        //FLOW THROUGH
        case EValueTypeNone:
        default:
            {
            break;
            }
        };
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::DataSize()
// -----------------------------------------------------------------------------
//
TInt CIMPSSAPKeyValuePair::DataSize() const
    {
    // extension space == 4 bytes
    // keyLength == 4 bytes
    // valueType == 1 bytes
    // ==> 9 bytes
    TInt dataSize = 9;

    dataSize += iKey->Length();

    switch ( iValueType )
        {
        case EValueTypeInt:
            {
            //Integer == 4 bytes
            dataSize += 4;
            break;
            }

        case EValueTypeDesC8:
            {
            //desc8 length == 4 bytes
            dataSize += 4;
            dataSize += iBuf8->Size();
            break;
            }

        case EValueTypeDesC16:
            {
            //desc16 length == 4 bytes
            dataSize += 4;
            dataSize += iBuf16->Size();
            break;
            }

        //FLOW THROUGH
        case EValueTypeNone:
        default:
            {
            break;
            }
        };

    return dataSize;
    }

// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::DataSizeDec()
// -----------------------------------------------------------------------------
//
TInt CIMPSSAPKeyValuePair::DataSizeDec() const
    {

    TInt dataSize( iKey->Length() );

    switch ( iValueType )
        {
        case EValueTypeInt:
            {
            dataSize += KTIntMaxLengthTextual;
            break;
            }

        case EValueTypeDesC8:
            {
            dataSize += iBuf8->Length();
            break;
            }

        case EValueTypeDesC16:
            {
            dataSize += iBuf16->Length();
            break;
            }

        //FLOW THROUGH
        case EValueTypeNone:
        default:
            {
            break;
            }
        };

    return dataSize;
    }

// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::IsDataTooBig()
// -----------------------------------------------------------------------------
//
TBool CIMPSSAPKeyValuePair::IsDataTooBig() const
    {
    return ( DataSizeDec() > ( NCentralRepositoryConstants::KMaxUnicodeStringLength -
                               2*KKeyValuePairFieldSeparator().Length() - 1 ) );
    }

// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::KeyValuePairFlatLC()
// -----------------------------------------------------------------------------
//

HBufC* CIMPSSAPKeyValuePair::KeyValuePairFlatLC()
    {

    // reserve memory for 2 field separators
    HBufC* flatBuf = HBufC::NewLC( NCentralRepositoryConstants::KMaxUnicodeStringLength );

    TPtr flatBufPtr( flatBuf->Des() );

    flatBufPtr.Append( *iKey );
    flatBufPtr.Append( KKeyValuePairFieldSeparator );
    flatBufPtr.AppendNum( iValueType, EDecimal );
    flatBufPtr.Append( KKeyValuePairFieldSeparator );

    switch ( iValueType )
        {
        case EValueTypeInt:
            {
            flatBufPtr.AppendNum( iInt );
            break;
            }

        case EValueTypeDesC8:
            {
            //convert to 16-bit
            TPtrC16 dataPtr16( ( TUint16* ) iBuf8->Ptr(), ( iBuf8->Size() / 2 ) );
            flatBufPtr.Append( dataPtr16 );
            break;
            }

        case EValueTypeDesC16:
            {
            flatBufPtr.Append( *iBuf16 );
            break;
            }

        //FLOW THROUGH
        case EValueTypeNone:
        default:
            {
            break;
            }
        };
    return flatBuf;
    }


// -----------------------------------------------------------------------------
// CIMPSSAPKeyValuePair::ParseFlatKeyValuePairL()
// -----------------------------------------------------------------------------
//

void CIMPSSAPKeyValuePair::ParseFlatKeyValuePairL( const TDesC& aKeyValuePairFlat )
    {
    TInt offset( aKeyValuePairFlat.Find( KKeyValuePairFieldSeparator ) );
    TInt offset2( aKeyValuePairFlat.Mid( offset +
                                         KKeyValuePairFieldSeparator().Length() ).Find(
                      KKeyValuePairFieldSeparator )
                );

    if ( ( offset == KErrNotFound ) || ( offset2 == KErrNotFound ) )
        {
        //Incorrect format, leave
        User::Leave( KErrNotFound );
        }

    TPtrC key( aKeyValuePairFlat.Left( offset ) );

    iKey = key.AllocL();

    TPtrC valueType( aKeyValuePairFlat.Mid( offset +
                                            KKeyValuePairFieldSeparator().Length(), offset2 ) );
    TLex lexer( valueType );
    TInt valueTypeInt( 0 );
    User::LeaveIfError( lexer.Val( valueTypeInt ) );
    TPtrC value( aKeyValuePairFlat.Mid( offset + offset2 +
                                        2*KKeyValuePairFieldSeparator().Length() ) ); // skip 2 separators
    switch ( valueTypeInt )
        {
        case EValueTypeInt:
            {
            TLex lexer( value );
            TInt intValue( 0 );
            User::LeaveIfError( lexer.Val( intValue ) );
            User::LeaveIfError( SetValue( intValue ) );
            break;
            }
        case EValueTypeDesC8:
            {
            //convert to 8-bit
            TPtrC8 dataPtr8( ( TUint8* ) value.Ptr(), value.Size() );
            User::LeaveIfError( SetValue( dataPtr8 ) );
            break;
            }
        case EValueTypeDesC16:
            {
            User::LeaveIfError( SetValue( value ) );
            break;
            }

        //FLOW THROUGH
        case EValueTypeNone:
        default:
            {
            break;
            }
        }
    }










//  End of File