--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wvsettings20/IMPSSrc/CIMPSSAPKeyValuePair.cpp Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,651 @@
+/*
+* 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
+