applayerprotocols/httptransportfw/core/chttpformencoder.cpp
changeset 0 b16258d2340f
child 17 8f055b80aa5b
child 23 ea9c9681bbaf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/core/chttpformencoder.cpp	Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,166 @@
+// CHTTPFormEncoder.cpp
+
+// Copyright (c) 2001-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:
+//
+
+// System includes
+#include <chttpformencoder.h> // Class signature
+#include <httperr.h>
+
+// Local includes
+
+
+const TInt KFormEncoderBufferIncrementSize = 256;
+
+EXPORT_C CHTTPFormEncoder* CHTTPFormEncoder::NewL()
+	{
+	CHTTPFormEncoder* self = new (ELeave) CHTTPFormEncoder();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+EXPORT_C CHTTPFormEncoder::~CHTTPFormEncoder()
+	{
+	__ASSERT_DEBUG(iState != ESupplyingData,HTTPPanic::Panic(HTTPPanic::EHTTPFormDataUnreleased));
+	delete iData;
+	}
+
+CHTTPFormEncoder::CHTTPFormEncoder() 
+	{}
+
+void CHTTPFormEncoder::ConstructL()
+	{
+	iData = HBufC8::NewL(KFormEncoderBufferIncrementSize);
+	}
+
+
+TBool CHTTPFormEncoder::GetNextDataPart(TPtrC8& aDataPart)
+	{
+	aDataPart.Set(*iData);
+	iState = ESupplyingData;
+	return ETrue;
+	}
+
+
+ void CHTTPFormEncoder::ReleaseData()
+	{
+	iState = EDataReleased;
+	}
+
+	
+TInt CHTTPFormEncoder::OverallDataSize()
+	{
+	iState = ESuppliedSize;
+	return iData->Size();
+	}
+	
+TInt CHTTPFormEncoder::Reset()
+	{
+	// Not implemented here
+	return KErrNotSupported;
+	}
+
+EXPORT_C void CHTTPFormEncoder::AddFieldL(const TDesC8& aFieldName, const TDesC8& aFieldValue)
+	{
+	__ASSERT_DEBUG(iState==EAllowAppendData, HTTPPanic::Panic(HTTPPanic::EHTTPFormSupplyingData));
+	if (!aFieldName.Length())
+		User::Leave(KErrArgument);
+
+	// The maximum size is if every single character would have to be encoded as its hex equivalent. 
+	// That is %HH. Also need to add room for the '=' and '&' field separator
+	TInt reqSize = (aFieldName.Length() + aFieldValue.Length())*3 +2;
+
+	if (!iData)
+		iData = HBufC8::NewL(reqSize);
+	else
+		{
+		TInt currentLength = iData->Length();
+		if (reqSize + currentLength > iData->Des().MaxLength())
+			{
+			TInt amountToGrow = reqSize < KFormEncoderBufferIncrementSize? KFormEncoderBufferIncrementSize : reqSize;
+			iData = iData->ReAllocL(amountToGrow+currentLength);
+			}
+		}
+
+	if (iData->Length() >0)
+		iData->Des().Append('&');
+	AppendData(aFieldName);
+	iData->Des().Append('=');
+	AppendData(aFieldValue);
+	}
+
+
+TBool CHTTPFormEncoder::IsAlphaNumeric(TUint8 aChar)
+	{
+	return (aChar >= 'a' && aChar <= 'z') ||
+		(aChar >= 'A' && aChar <= 'Z') ||
+		(aChar >= '0' && aChar <='9');
+	}
+
+
+/** Appends a non alpha numeric character by converting it to %HH where HH is the Hexadecmial representation
+of the character
+*/
+void CHTTPFormEncoder::AppendSpecialChar(TUint8 aChar)
+	{
+	TPtr8 dataPtr = iData->Des();
+	dataPtr.Append('%');
+
+	TUint hexChar = aChar/16;
+	hexChar = hexChar > 9 ? hexChar + 55 : hexChar + 48;
+	dataPtr.Append(hexChar);
+
+	hexChar= aChar%16;
+	hexChar = hexChar > 9 ? hexChar + 55 : hexChar + 48;
+	dataPtr.Append(hexChar);
+	}
+
+void CHTTPFormEncoder::AppendData(const TDesC8& aData)
+	{
+	TBool hadCR  = EFalse;                                
+	TInt length = aData.Length();
+	for (TInt ii=0; ii<length; ++ii)
+		{
+		TPtr8 dataPtr = iData->Des();
+		TUint8 charToProcess = aData[ii];
+
+		if (charToProcess == 0x0d)	// turn CR into CR/LF
+			{
+			hadCR = ETrue;
+			AppendSpecialChar(charToProcess);
+			AppendSpecialChar(0x0a);
+			continue;
+			}
+
+		if (hadCR)
+			{
+			hadCR = EFalse;
+			if (charToProcess == 0x0a) // LF after a CR, so skip as already appended
+				continue;
+			}
+
+		// handle spaces -> become +
+		if (charToProcess == ' ')
+			dataPtr.Append('+');
+		// handle normal character
+		else if (IsAlphaNumeric(charToProcess))
+			dataPtr.Append((TChar)charToProcess);
+		else 
+			AppendSpecialChar(charToProcess); // encode to %HH
+		//
+		}
+	}