natfw/natfwunsaf_protocols/unsaf_codec/src/natfwunsafattribute.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/natfw/natfwunsaf_protocols/unsaf_codec/src/natfwunsafattribute.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,157 @@
+/*
+* Copyright (c) 2006-2007 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:   
+*
+*/
+
+
+
+
+#include <es_sock.h>
+#include "natfwunsafattribute.h"
+#include "natfwunsafutils.h"
+
+// -----------------------------------------------------------------------------
+// CNATFWUNSAFAttribute::CNATFWUNSAFAttribute
+// -----------------------------------------------------------------------------
+//
+CNATFWUNSAFAttribute::CNATFWUNSAFAttribute()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CNATFWUNSAFAttribute::~CNATFWUNSAFAttribute
+// -----------------------------------------------------------------------------
+//
+CNATFWUNSAFAttribute::~CNATFWUNSAFAttribute()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CNATFWUNSAFAttribute::EncodeL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CNATFWUNSAFAttribute::EncodeL() const
+    {
+    HBufC8* value = EncodeValueL();
+    CleanupStack::PushL(value);
+    TInt attrValLength = value->Length();
+
+    //Pad non-DWORD-boundary aligned attributes with spaces if needed. Spaces
+    //used instead of \0 in order to not mess up buggy C implementations.
+    const TInt KGranularity = 4;
+    TInt bytesInLastBlock = attrValLength % KGranularity;
+    TInt bytesToAppend = KGranularity - bytesInLastBlock;
+    if (0 < bytesInLastBlock && !IsWordBoundaryAligned(Type()))
+        {
+        CBufBase* valueBuf = CBufFlat::NewL(attrValLength + bytesToAppend);
+        CleanupStack::PushL(valueBuf);
+        valueBuf->InsertL(0, *value, attrValLength);
+        const TChar KSpace(' ');
+        for (TInt i = 0; i < bytesToAppend; ++i)
+            {
+            valueBuf->InsertL(valueBuf->Size(), &KSpace, 1);
+            }
+        // Store value pointer for proper cleanupstack handling
+        HBufC8* oldValue = value;
+        value = valueBuf->Ptr(0).AllocL();
+        CleanupStack::PopAndDestroy(valueBuf);
+        CleanupStack::PopAndDestroy( oldValue );
+        CleanupStack::PushL( value );
+        }
+
+    HBufC8* attribute = HBufC8::NewLC(value->Length() + EValueOffset);
+    TPtr8 ptr = attribute->Des();
+    ptr.FillZ(EValueOffset);
+
+    NATFWUNSAFUtils::WriteNetworkOrder16L(ptr, ETypeOffset, Type());
+    NATFWUNSAFUtils::WriteNetworkOrder16L(ptr,
+                                     ELengthOffset,
+                                     static_cast<TUint16>(attrValLength));
+    ptr.Append(*value);
+    CleanupStack::Pop(attribute);
+    CleanupStack::PopAndDestroy(value);
+
+    return attribute;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATFWUNSAFAttribute::ParseLengthL
+// -----------------------------------------------------------------------------
+//
+TUint16 CNATFWUNSAFAttribute::ParseLengthL(const TDesC8& aByteStream)
+    {
+    __ASSERT_ALWAYS(aByteStream.Length() >= EValueOffset,
+                    User::Leave(KErrArgument));
+
+    return BigEndian::Get16(aByteStream.Mid(ELengthOffset).Ptr());
+    }
+
+// -----------------------------------------------------------------------------
+// CNATFWUNSAFAttribute::ParseTypeAndLengthL
+// -----------------------------------------------------------------------------
+//
+void CNATFWUNSAFAttribute::ParseTypeAndLengthL(const TDesC8& aByteStream,
+                                           TUint16& aType,
+                                           TUint16& aTotalLength)
+    {
+    //Stream must have enough data to contain at least an attribute with
+    //zero-length value
+    __ASSERT_ALWAYS(aByteStream.Length() >= EValueOffset,
+                    User::Leave(KErrArgument));
+
+    TUint16 totalLength = ParseLengthL(aByteStream) + EValueOffset;
+
+    //Increase total length if it's not a multiple of 4 bytes.
+    //This is because of possible padding in text attributes not visible from
+    //attribute length field.
+    const TUint16 KGranularity = 4;
+    TUint16 bytesInLastBlock = totalLength % KGranularity;
+    TUint16 bytesPadded = KGranularity - bytesInLastBlock;
+    if (0 < bytesInLastBlock )
+        {
+        totalLength += bytesPadded;
+        }
+
+    __ASSERT_ALWAYS(aByteStream.Length() >= totalLength,
+                    User::Leave(KErrArgument));
+
+    aTotalLength = totalLength;
+    aType = BigEndian::Get16(aByteStream.Mid(ETypeOffset).Ptr());
+    }
+
+// -----------------------------------------------------------------------------
+// CNATFWUNSAFAttribute::IsMandatory
+// -----------------------------------------------------------------------------
+//
+TBool CNATFWUNSAFAttribute::IsMandatory(TUint16 aType)
+    {
+    const TInt KLargestMandatoryValue = 0x7fff; //RFC 3489
+    return aType <= KLargestMandatoryValue;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATFWUNSAFAttribute::IsWordBoundaryAligned
+// -----------------------------------------------------------------------------
+//
+TBool CNATFWUNSAFAttribute::IsWordBoundaryAligned(TUint16 aType)
+    {
+    return !(aType == EUsername ||
+             aType == EPassword ||
+             aType == EData     ||
+             aType == EServer   ||
+             aType == ENonce    ||
+             aType == ERealm    ||
+             aType == EErrorCode);
+    }