diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SDP/src/SdpKeyField.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SDP/src/SdpKeyField.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,525 @@ +// Copyright (c) 2003-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: +// Name : SdpKeyField.h +// Part of : SDP Codec +// Version : 1.0 +// + + + +#include +#include +#include "SdpKeyField.h" +#include "SdpUtil.h" +#include "SDPCodec.pan" +#include "_sdpdefs.h" +#include "sdpcodecstringconstants.h" +#include "SdpCodecConstants.h" +#include "SdpCodecErr.h" +#include "SdpCodecStringPool.h" + +// LOCAL CONSTANTS +const TText8 KPlusChar = '+'; + +// ----------------------------------------------------------------------------- +// CSdpKeyField::DecodeL +// Decodes key field from TDesC +// ----------------------------------------------------------------------------- +// +EXPORT_C CSdpKeyField* CSdpKeyField::DecodeL(const TDesC8& aFieldValue) + { + CSdpKeyField* obj = DecodeLC(aFieldValue); + CleanupStack::Pop(); + return obj; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::DecodeL +// Decodes key field from TDesC +// ----------------------------------------------------------------------------- +// +EXPORT_C CSdpKeyField* CSdpKeyField::DecodeLC(const TDesC8& aFieldValue) + { + CSdpKeyField* obj = new (ELeave) CSdpKeyField(); + CleanupStack::PushL(obj); + obj->ConstructL(aFieldValue); + return obj; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::NewL +// Two-phased constructor +// ----------------------------------------------------------------------------- +// +EXPORT_C CSdpKeyField* CSdpKeyField::NewL(RStringF aMethod, + const TDesC8& aEncryptionKey) + { + CSdpKeyField* obj = NewLC(aMethod, aEncryptionKey); + CleanupStack::Pop(); + return obj; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::NewLC +// Two-phased constructor +// ----------------------------------------------------------------------------- +// +EXPORT_C CSdpKeyField* CSdpKeyField::NewLC(RStringF aMethod, + const TDesC8& aEncryptionKey) + { + CSdpKeyField* obj = new (ELeave) CSdpKeyField(); + CleanupStack::PushL(obj); + obj->ConstructL(aMethod, aEncryptionKey); + return obj; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::~CSdpKeyField +// Destructor +// ----------------------------------------------------------------------------- +// +EXPORT_C CSdpKeyField::~CSdpKeyField() + { + iMethod.Close(); + delete iEncryptionKey; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::EncodeL +// Writes attributes in proper format to the stream +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSdpKeyField::EncodeL(RWriteStream& aStream) const + { + __TEST_INVARIANT; + RStringF header = iStringPool.StringF(SdpCodecStringConstants::EKey, + SdpCodecStringConstants::Table); + aStream.WriteL( header.DesC() ); + + aStream.WriteL( iMethod.DesC() ); + if (iMethod != iStringPool.StringF(SdpCodecStringConstants::EMethodPrompt, + SdpCodecStringConstants::Table)) + { + aStream.WriteL( KColonStr ); + if (iEncryptionKey->Length() > 0) + { + aStream.WriteL( *iEncryptionKey ); + } + } + + aStream.WriteL( KCRLFStr ); + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::CloneL +// Creates an exact copy of the key field +// ----------------------------------------------------------------------------- +// +EXPORT_C CSdpKeyField * CSdpKeyField::CloneL() const + { + __TEST_INVARIANT; + CSdpKeyField* obj = CSdpKeyField::NewL(iMethod, *iEncryptionKey); + __ASSERT_DEBUG(*this == *obj, User::Panic( KSdpCodecPanicCat, + KSdpCodecPanicInternal)); + return obj; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::operator == +// Checks if two key fields are equal +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CSdpKeyField::operator == (const CSdpKeyField& aObj) const + { + __TEST_INVARIANT; + return iMethod == aObj.iMethod + && ((iEncryptionKey == 0 && aObj.iEncryptionKey == 0) + || (iEncryptionKey != 0 && aObj.iEncryptionKey != 0 + && aObj.iEncryptionKey->Compare(*iEncryptionKey) == 0)); + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::Method +// Returns method +// ----------------------------------------------------------------------------- +// +EXPORT_C RStringF CSdpKeyField::Method() const + { + __TEST_INVARIANT; + return iMethod; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::EncryptionKey +// Returns encryption key +// ----------------------------------------------------------------------------- +// +EXPORT_C const TDesC8& CSdpKeyField::EncryptionKey() const + { + __TEST_INVARIANT; + return *iEncryptionKey; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::SetL +// Sets new values to key method and encryption key +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSdpKeyField::SetL(RStringF aMethod, + const TDesC8& aEncryptionKey) + { + RStringF methodClear = iStringPool.StringF( + SdpCodecStringConstants::EMethodClear, + SdpCodecStringConstants::Table ); + RStringF methodBase64 = iStringPool.StringF( + SdpCodecStringConstants::EMethodBase64, + SdpCodecStringConstants::Table ); + RStringF methodUri = iStringPool.StringF( + SdpCodecStringConstants::EMethodUri, + SdpCodecStringConstants::Table ); + RStringF methodPrompt = iStringPool.StringF( + SdpCodecStringConstants::EMethodPrompt, + SdpCodecStringConstants::Table ); + + if (aMethod == methodClear) + { + SetMethodClearAndKeyL(methodClear, aEncryptionKey); + } + else if (aMethod == methodBase64) + { + SetMethodBase64AndKeyL(methodBase64, aEncryptionKey); + } + else if (aMethod == methodUri) + { + SetMethodUriAndKeyL(methodUri, aEncryptionKey); + } + else if (aMethod == methodPrompt) + { + SetMethodPromptL(methodPrompt, aEncryptionKey); + } + else + { + User::Leave(KErrSdpCodecKeyField); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::ExternalizeL +// Externalizes the object to stream +// ----------------------------------------------------------------------------- +// +void CSdpKeyField::ExternalizeL(RWriteStream& aStream) const + { + aStream.WriteUint32L( iMethod.DesC().Length() ); + aStream.WriteL( iMethod.DesC() ); + + aStream.WriteUint32L( iEncryptionKey->Des().Length() ); + if (iEncryptionKey->Des().Length() > 0) + { + aStream.WriteL(iEncryptionKey->Des(), iEncryptionKey->Des().Length()); + } + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::InternalizeL +// Internalizes the object from stream +// ----------------------------------------------------------------------------- +// +CSdpKeyField* CSdpKeyField::InternalizeL(RReadStream& aStream) + { + CSdpKeyField* self = new (ELeave) CSdpKeyField(); + CleanupStack::PushL(self); + self->iStringPool = SdpCodecStringPool::StringPoolL(); + + self->DoInternalizeL(aStream); + + CleanupStack::Pop(); // self + return self; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::CSdpKeyField +// Constructor +// ----------------------------------------------------------------------------- +// +CSdpKeyField::CSdpKeyField() + { + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CSdpKeyField::ConstructL(const TDesC8& aText) + { + iStringPool = SdpCodecStringPool::StringPoolL(); + RArray lines; + lines = SdpUtil::DivideToLinesL(aText, KErrSdpCodecKeyField); + CleanupClosePushL(lines); + + TLex8 lexer(lines[0]); + RArray keyArray = GetElementsFromLineL(lexer); + CleanupClosePushL(keyArray); + const TDesC8& keyName = iStringPool.StringF(SdpCodecStringConstants::EKey, + SdpCodecStringConstants::Table).DesC(); + + __ASSERT_ALWAYS(lines.Count() == 1 + && keyArray.Count() >= 2 && keyArray.Count() <= 3 + && keyArray[0].Find(keyName) != KErrNotFound, + User::Leave(KErrSdpCodecKeyField)); + + RStringF method = iStringPool.OpenFStringL(keyArray[1]); + CleanupClosePushL(method); + + if (keyArray.Count() == 3) + { + SetL(method, keyArray[2]); + } + else + { + SetL(method, KNullDesC8); + } + CleanupStack::PopAndDestroy(3); // method, lines, keyArray + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CSdpKeyField::ConstructL(RStringF aMethod, const TDesC8& aEncryptionKey) + { + iStringPool = SdpCodecStringPool::StringPoolL(); + SetL(aMethod, aEncryptionKey); + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::DoInternalizeL +// Internalizes the object members from stream +// ----------------------------------------------------------------------------- +// +void CSdpKeyField::DoInternalizeL(RReadStream& aStream) + { + // + TUint32 length = aStream.ReadUint32L(); + HBufC8* method = HBufC8::NewLC(length); + TPtr8 ptr(method->Des()); + aStream.ReadL(ptr, length); + + RStringF methodStr = iStringPool.OpenFStringL(*method); + CleanupStack::PopAndDestroy(); // method + CleanupClosePushL(methodStr); + + length = aStream.ReadUint32L(); + if (length > 0) + { + HBufC8* key = HBufC8::NewLC(length); + ptr.Set(key->Des()); + aStream.ReadL(ptr, length); + + SetL(methodStr, *key); + CleanupStack::PopAndDestroy(); //key + } + else + { + SetL(methodStr, KNullDesC8); + } + CleanupStack::PopAndDestroy(); // methodStr + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::SetMethodAndKeyL +// Sets new values to key method and encryption key +// ----------------------------------------------------------------------------- +// +void CSdpKeyField::SetMethodAndKeyL(RStringF aMethod, + const TDesC8& aEncryptionKey, + TBool aAllowEmptyKeyValue) + { + HBufC8* tempKey = aEncryptionKey.AllocL(); + tempKey->Des().Trim(); + if (tempKey->Length() == 0 && !aAllowEmptyKeyValue) + { + delete tempKey; + User::Leave(KErrSdpCodecKeyField); + } + iMethod.Close(); + iMethod = aMethod.Copy(); + delete iEncryptionKey; + iEncryptionKey = tempKey; + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::SetMethodClearAndKeyL +// Sets key method to clear and new encryption key +// ----------------------------------------------------------------------------- +// +void CSdpKeyField::SetMethodClearAndKeyL(RStringF aMethod, + const TDesC8& aEncryptionKey) + { + __ASSERT_ALWAYS(SdpUtil::IsByteString(aEncryptionKey), + User::Leave(KErrSdpCodecKeyField)); + SetMethodAndKeyL(aMethod, aEncryptionKey, EFalse); + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::SetMethodBase64AndKeyL +// Sets key method to Base64 and new encryption key +// ----------------------------------------------------------------------------- +// +void CSdpKeyField::SetMethodBase64AndKeyL(RStringF aMethod, + const TDesC8& aText) + { + __ASSERT_ALWAYS(aText.Length() > 0, User::Leave(KErrSdpCodecKeyField)); + + for (TInt i = 0; i < aText.Length(); i++) + { + if ( !( ( aText[i] >= 'a' && aText[i] <= 'z' ) || + ( aText[i] >= 'A' && aText[i] <= 'Z' ) || + ( aText[i] >= '0' && aText[i] <= '9' ) || + ( aText[i] == KPlusChar ) || + ( aText[i] == KSlashChar ) || + ( aText[i] == KEqualChar ) ) ) + { + User::Leave(KErrSdpCodecKeyField); + } + } + SetMethodAndKeyL(aMethod, aText, EFalse); + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::SetMethodUriAndKeyL +// Sets key method to uri and new encryption key +// ----------------------------------------------------------------------------- +// +void CSdpKeyField::SetMethodUriAndKeyL(RStringF aMethod, const TDesC8& aText) + { + TUriParser8 parser; + User::LeaveIfError(parser.Parse(aText)); + SetMethodAndKeyL(aMethod, aText, EFalse); + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::SetMethodPromptL +// Sets key method to Prompt and new encryption key +// ----------------------------------------------------------------------------- +// +void CSdpKeyField::SetMethodPromptL(RStringF aMethod, const TDesC8& aText) + { + __ASSERT_ALWAYS(aText.Length() == 0, User::Leave(KErrSdpCodecKeyField)); + SetMethodAndKeyL(aMethod, aText, ETrue); + } + +// ----------------------------------------------------------------------------- +// CSdpKeyField::GetElementsFromLineL +// Gets all the elements from a single line +// ----------------------------------------------------------------------------- +// +RArray CSdpKeyField::GetElementsFromLineL( TLex8& aLexer) + { + RArray lineArray; + CleanupClosePushL(lineArray); + + aLexer.Mark(); + for (TChar curChar(KColonChar); curChar != KEqualChar;) + { + curChar = aLexer.Peek(); + if (curChar == KEofChar || curChar == KLFChar || + curChar == KCRChar) + { + User::Leave(KErrSdpCodecKeyField); + } + aLexer.Inc(); + } + User::LeaveIfError(lineArray.Append(aLexer.MarkedToken())); + + TBool colonFound = EFalse; + TBool eofcFound = EFalse; + while (!eofcFound) + { + aLexer.Mark(); + while ((aLexer.Peek() != KColonChar || colonFound) && + aLexer.Peek() != KCRChar && + aLexer.Peek() != KLFChar && + aLexer.Peek() != KEofChar) + { + aLexer.Inc(); + } + + if (aLexer.MarkedToken().Length() > 0) + { + User::LeaveIfError(lineArray.Append(aLexer.MarkedToken())); + } + else + { + User::Leave(KErrSdpCodecKeyField); + } + + if (aLexer.Peek() == KColonChar) + { + colonFound = ETrue; + } + + if (aLexer.Peek() == KCRChar) + { + aLexer.Inc(); + } + if (aLexer.Peek() == KLFChar) + { + aLexer.Inc(); + if (aLexer.Peek() == KEofChar) + { + eofcFound = ETrue; + } + } + else + { + aLexer.Inc(); + } + } + + CleanupStack::Pop(); + return lineArray; + } + +void CSdpKeyField::__DbgTestInvariant() const + { + RStringF methodClear = iStringPool.StringF( + SdpCodecStringConstants::EMethodClear, + SdpCodecStringConstants::Table ); + RStringF methodBase64 = iStringPool.StringF( + SdpCodecStringConstants::EMethodBase64, + SdpCodecStringConstants::Table ); + RStringF methodUri = iStringPool.StringF( + SdpCodecStringConstants::EMethodUri, + SdpCodecStringConstants::Table ); + RStringF methodPrompt = iStringPool.StringF( + SdpCodecStringConstants::EMethodPrompt, + SdpCodecStringConstants::Table ); + + TBool invariant = (iMethod == methodPrompt + && (iEncryptionKey != 0 && (iEncryptionKey->Length() == 0)) ) + || ((iMethod == methodClear || iMethod == methodBase64 + || iMethod == methodUri) + && (iEncryptionKey != 0 && (iEncryptionKey->Length() != 0)) ); + + if (!invariant) + User::Invariant(); + }