diff -r 000000000000 -r 094583676ce7 wvsettings20/IMPSSrc/CIMPSSAPKeyValuePair.cpp --- /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 // for unicode character conversions +#include +#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 +