applayerprotocols/httptransportfw/Test/t_httpmessage/cmessagecomposerdriver.cpp
changeset 0 b16258d2340f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/t_httpmessage/cmessagecomposerdriver.cpp	Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,504 @@
+// Copyright (c) 2002-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:
+//
+
+#include "cmessagecomposerdriver.h"
+
+#include "mdriverobserver.h"
+#include "cbodydatasupplier.h"
+
+CMessageComposerDriver* CMessageComposerDriver::NewL(MDriverObserver& aObserver)
+	{
+	CMessageComposerDriver* self = new(ELeave) CMessageComposerDriver(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CMessageComposerDriver::~CMessageComposerDriver()
+	{
+	iHeaders.Close();
+	iTrailers.Close();
+	iMessageComposer.Close();
+	delete iBodyData;
+	}
+
+CMessageComposerDriver::CMessageComposerDriver(MDriverObserver& aObserver)
+: CActive(CActive::EPriorityStandard), iObserver(aObserver)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CMessageComposerDriver::ConstructL()
+	{
+	iMessageComposer.OpenL(*this);
+	}
+
+void CMessageComposerDriver::SetMessageData(const TDesC8& aMessageData)
+	{
+	iMessageData.Set(aMessageData);
+	}
+
+void CMessageComposerDriver::SetStartLine(const TDesC8& aToken1, const TDesC8& aToken2, const TDesC8& aToken3)
+	{
+	iStartLine1.Set(aToken1);
+	iStartLine2.Set(aToken2);
+	iStartLine3.Set(aToken3);
+	}
+
+void CMessageComposerDriver::SetHeaderL(const TDesC8& aFieldName, const TDesC8& aFieldValue)
+	{
+	User::LeaveIfError(iHeaders.Append(THeaderField(aFieldName, aFieldValue)));
+	}
+
+void CMessageComposerDriver::SetBodyDataL(const TDesC8& aBodyPart)
+	{
+	if( iBodyData == NULL )
+		iBodyData = CBodyDataSupplier::NewL(*this);
+
+	iBodyData->AddBodyPartL(aBodyPart);
+	}
+
+void CMessageComposerDriver::SetBodySize(TInt aSize)
+	{
+	__ASSERT_DEBUG( iBodyData, User::Invariant() );
+	
+	iBodyData->SetBodySize(aSize);
+	}
+
+void CMessageComposerDriver::SetTrailerL(const TDesC8& aFieldName, const TDesC8& aFieldValue)
+	{
+	User::LeaveIfError(iTrailers.Append(THeaderField(aFieldName, aFieldValue)));
+	}
+
+void CMessageComposerDriver::Start(TInt aExpectedError, TBool aTestReset)
+	{
+	iExpectedError	= aExpectedError;
+	iDoReset		= aTestReset;
+
+	// Inform the observer that the test has started
+	iObserver.NotifyStart();
+
+	// Set the reset state to initial state - PendingStartLine.
+	iResetState = EPendingStartLine;
+
+	// Self-complete to kick-off the test.
+	CompleteSelf();
+	}
+
+void CMessageComposerDriver::CompleteSelf()
+	{
+	TRequestStatus* pStat = &iStatus;
+	User::RequestComplete(pStat, KErrNone);
+	SetActive();
+	}
+
+void CMessageComposerDriver::DoReset()
+	{
+	// Reset the composer and update the reset state.
+	iMessageComposer.Reset();
+	iResetState = iState;
+
+	iObserver.Log(_L("RESET - starting test again!!"));
+
+	// Reset the data supplier
+	if( iBodyData != NULL )
+		iBodyData->ResetSupplier();
+
+	if( iState == EPendingNextHeader )
+		iResetIndex = iHeaderIndex;
+	else if( iState == EPendingNextTrailer )
+		iResetIndex = iTrailerIndex;
+	else if( iState == EPendingHasBody )
+		iChunkIndex = 0;
+
+	// Start the test over...
+	CompleteSelf();
+	}
+
+/*
+ *	Methods from CActive
+ */
+
+void CMessageComposerDriver::RunL()
+	{
+	// Reset the indexes
+	iHeaderIndex = 0;
+	iTrailerIndex = 0;
+
+	// Set the reset flags
+	iReset			= EFalse;
+	iMessageChunk	= 0;
+	iChunkCount		= 0;
+
+	// Reset the expected data..
+	iExpectedData.Set(iMessageData);
+
+	// Start the composer...
+	iMessageComposer.MessageInfoAvailable();
+
+	// Move to PendingStartLine state...
+	iState = EPendingStartLine;
+	}
+
+void CMessageComposerDriver::DoCancel()
+	{
+	// Do nothing...
+	}
+
+TInt CMessageComposerDriver::RunError(TInt aError)
+	{
+	// Inform the observer of the error
+	iObserver.NotifyError(aError);
+
+	return KErrNone;
+	}
+
+/*
+ *	Methods from MHttpMessageComposerObserver
+ */
+
+void CMessageComposerDriver::StartLineL(TPtrC8& aToken1, TPtrC8& aToken2, TPtrC8& aToken3)
+	{
+	__ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() );
+
+	iObserver.Log(_L("StartLineL received"));
+
+	// Was StartLineL expected?
+	if( iState != EPendingStartLine || iReset )
+		{
+		// Not expecting start-line. Test has failed - notify the observer.
+		iObserver.Log(_L("FAIL - not expecting StartLineL request"));
+		iObserver.NotifyError(KErrNotFound);
+		iTestFailed = ETrue;
+		}
+	else
+		{
+		// Should a reset occur here?
+		if( iDoReset && iResetState == iState )
+			iReset = ETrue;
+
+		// Set the tokens...
+		aToken1.Set(iStartLine1);
+		aToken2.Set(iStartLine2);
+		aToken3.Set(iStartLine3);
+
+		// Set the next state...
+		iState = EPendingNextHeader;
+        // We no longer compose line by line. We compose startline & headers (6) at one go.
+        // We cannot reset here
+        iReset = EFalse;
+		if( iReset )
+			DoReset();
+		}
+	}
+
+TInt CMessageComposerDriver::NextHeaderL(TPtrC8& aHeaderName, TPtrC8& aHeaderValue)
+	{
+	__ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() );
+
+	iObserver.Log(_L("NextHeaderL received"));
+
+	// Was NextHeaderL expected?
+	TInt error = ( iHeaderIndex < iHeaders.Count() ) ? KErrNone : KErrNotFound;
+	if( iState != EPendingNextHeader || iReset )
+		{
+		// Not expecting NextHeader. Test has failed - reset the composer and
+		// notify the observer.
+		iObserver.Log(_L("FAIL - not expecting NextHeaderL request"));
+		iObserver.NotifyError(KErrNotFound);
+		iTestFailed = ETrue;
+		}
+	else
+		{
+		// Should a reset occur here?
+		if( iDoReset && (iResetState == iState && iResetIndex == iHeaderIndex) )
+			iReset = ETrue;
+
+		// Are there any headers left to give? 
+		if( iHeaderIndex < iHeaders.Count() )
+			{
+			// Give the current header info...
+			THeaderField header = iHeaders[iHeaderIndex];
+
+			aHeaderName.Set(header.iName);
+			aHeaderValue.Set(header.iValue);
+
+			// Loop to next header...
+			++iHeaderIndex;
+			}
+		else
+			{
+			// No more headers - change state
+			iState = EPendingHasBody;
+			}
+
+		if( iReset )
+			DoReset();
+		}
+	// Return KErrNotFound if this is the last header.
+	return error;
+	}
+
+MHTTPDataSupplier* CMessageComposerDriver::HasBodyL()
+	{
+	__ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() );
+
+	iObserver.Log(_L("HasBodyL received"));
+
+	// Was start-line expected?
+	if( iState != EPendingHasBody )
+		{
+		// Not expecting HasBodyL. Test has failed - notify the observer.
+		iObserver.Log(_L("FAIL - not expecting HasBodyL request"));
+		iObserver.NotifyError(KErrNotFound);
+		iTestFailed = ETrue;
+		}
+	else
+		{
+		// Should a reset occur here?
+//		if( iDoReset && iResetState == iState )
+//			iReset = ETrue;
+
+		// Set the next state...
+		if( iBodyData != NULL && iBodyData->IsChunked() )
+			{
+			// Have got a chunked body - expect NextTrailersL...
+			iState = EPendingNextTrailer;
+			}
+		else
+			{
+			// Either no body or non-encoded body - expect MessageComplete
+			iState = EPendingMessageComplete;
+			}
+
+//		if( iReset )
+// 		DoReset();
+		}
+	return iBodyData;
+	}
+
+TInt CMessageComposerDriver::NextTrailerL(TPtrC8& aHeaderName, TPtrC8& aHeaderValue)
+	{
+	__ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() );
+
+	iObserver.Log(_L("NextTrailerL received"));
+
+	// Was NextTrailerL expected?
+	TInt error = ( iTrailerIndex < iTrailers.Count() ) ? KErrNone : KErrNotFound;
+	if( iState != EPendingNextTrailer || iReset )
+		{
+		// Not expecting NextHeader. Test has failed - notify the observer.
+		iObserver.Log(_L("FAIL - not expecting NextTrailerL request"));
+		iObserver.NotifyError(KErrNotFound);
+		iTestFailed = ETrue;
+		}
+	else
+		{
+		// Should a reset occur here?
+		if( iDoReset && (iResetState == iState && iResetIndex == iTrailerIndex) )
+			iReset = ETrue;
+
+		// Are there any headers left to give? 
+		if( iTrailerIndex < iTrailers.Count() )
+			{
+			// Give the current header info...
+			THeaderField header = iTrailers[iTrailerIndex];
+
+			aHeaderName.Set(header.iName);
+			aHeaderValue.Set(header.iValue);
+
+			// Loop to next header...
+			++iTrailerIndex;
+			}
+		else
+			{
+			// No more trailers - change state
+			iState = EPendingMessageComplete;
+			}
+
+		if( iReset )
+			DoReset();
+		}
+	// Return KErrNotFound if this is the last header.
+	return error;
+	}
+
+void CMessageComposerDriver::MessageComplete()
+	{
+	__ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() );
+
+	// Log the message complete event
+	iObserver.Log(_L("Message Complete received"));
+
+	// Was this expected?
+	if( iState != EPendingMessageComplete || iReset )
+		{
+		// Not expecting message complete. Test has failed - notify the observer
+		iObserver.Log(_L("FAIL - not expecting message complete"));
+		iObserver.NotifyError(KErrNotFound);
+		iTestFailed = ETrue;
+		}
+	else
+		{
+		// Has all the data been received?
+		if( iExpectedData.Length() == 0 )
+			{
+			// Should a reset occur here?
+			if( iDoReset && iResetState == iState )
+				iReset = ETrue;
+
+			iState = EDone;
+
+			if( iReset )
+				DoReset();
+			else
+				{// Test done...
+				iObserver.NotifyComplete();
+				}
+			}
+		else
+			{
+			// Oh dear, not all data has been received - test failed.
+			iObserver.Log(_L("FAIL - all message data not received"));
+			iObserver.NotifyError(KErrNotFound);
+			iTestFailed = ETrue;
+			}
+		}
+	}
+
+void CMessageComposerDriver::MessageDataReadyL()
+	{
+	__ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() );
+
+	if( iReset )
+		{
+		// The composer has been reset - should not be receiving this. 
+		// Test has failed - notify the observer.
+		iObserver.Log(_L("FAIL - not expecting MessageDataReady"));
+		iObserver.NotifyError(KErrNotFound);
+		iTestFailed = ETrue;
+		}
+	else
+		{
+		// Get data from the composer
+		TPtrC8 data;
+		iMessageComposer.GetMessageData(data);
+
+		// Dump the message data...
+		iObserver.Log(_L("Message data received"));
+		iObserver.Dump(data);
+
+		// Check to see if it matches the expected data.
+		TBool match = EFalse;
+		if( data.Length() <= iExpectedData.Length() )
+			{
+			// Is the content the same
+			if( data.Compare(iExpectedData.Left(data.Length())) == 0 )
+				{
+				// Data is the same - update the expected data
+				iExpectedData.Set(iExpectedData.Mid(data.Length()));
+				match = ETrue;
+				}
+			}
+		if( match )
+			{
+			if( iDoReset && iMessageIndex == iMessageChunk )
+				{
+				// Reset the composer and update the chunk index
+				iMessageComposer.Reset();
+				++iMessageIndex;
+
+				iObserver.Log(_L("RESET - starting test again!!"));
+
+				// Reset the data supplier
+				if( iBodyData != NULL )
+					iBodyData->ResetSupplier();
+
+				// Start the test over...
+				CompleteSelf();
+				}
+			else
+				{
+				// Inc the message chunk count
+				++iMessageChunk;
+
+				// Release the message data...
+				iMessageComposer.ReleaseMessageData();
+				}
+			}
+		else
+			{
+			// The data does not match. Test has failed - notify the observer.
+			iObserver.Log(_L("FAIL - received incorrect data"));
+			iObserver.NotifyError(KErrNotFound);
+			iTestFailed = ETrue;
+			}
+		}
+	}
+
+TInt CMessageComposerDriver::HandleComposeError(TInt aError)
+	{
+	// Is an error expected?
+	if( iExpectedError == aError )
+		{
+		TBuf<64> comment;
+		comment.Format(_L("Received expected error : %d"), aError);
+		iObserver.Log(comment);
+
+		// Yep - test done...
+		iObserver.NotifyComplete();
+		}
+	else
+		{
+		// Inform the observer of the error
+		iObserver.NotifyError(aError);
+		}
+	return KErrNone;
+	}
+
+void CMessageComposerDriver::Reserved_MHttpMessageComposerObserver()
+	{
+	User::Invariant();
+	}
+
+/*
+ *	Methods from MBodyDataSupplierObserver
+ */
+
+void CMessageComposerDriver::NotifyMoreData()
+	{
+	if( iDoReset && iChunkIndex == iChunkCount )
+		{
+		// Reset the composer and update the chunk index
+		iMessageComposer.Reset();
+		++iChunkIndex;
+
+		iObserver.Log(_L("RESET - starting test again!!"));
+
+		// Reset the data supplier
+		if( iBodyData != NULL )
+			iBodyData->ResetSupplier();
+
+		// Start the test over...
+		CompleteSelf();
+		}
+	else
+		{
+		// Inc the chunk count and notify the composer of more data
+		++iChunkCount;
+		iMessageComposer.MessageInfoAvailable();
+		}
+	}