realtimenetprots/sipfw/SDP/src/SdpKeyField.cpp
changeset 0 307788aac0a8
--- /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 <uri8.h>
+#include <s32strm.h>
+#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 <TPtrC8> lines;
+    lines = SdpUtil::DivideToLinesL(aText, KErrSdpCodecKeyField);
+    CleanupClosePushL(lines);
+
+    TLex8 lexer(lines[0]);
+    RArray<TPtrC8> 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)
+    {
+     // <method>
+    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<TPtrC8> CSdpKeyField::GetElementsFromLineL( TLex8& aLexer)
+    {
+    RArray<TPtrC8> 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();
+	}