applayerprotocols/httpexamples/nwsswsptrhnd/CNwssTransLookUpTable.cpp
changeset 0 b16258d2340f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httpexamples/nwsswsptrhnd/CNwssTransLookUpTable.cpp	Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,247 @@
+// 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:
+// System includes
+// 
+//
+
+// Local includes
+#include "cnwsswsptrhnddatasupplier.h"
+#include "tnwsswsptrhndpanic.h"
+
+// Class signature
+#include "cnwsstranslookuptable.h"
+
+
+
+CNwssTransLookUpTable::CNwssTransLUTEntry* CNwssTransLookUpTable::CNwssTransLUTEntry::NewL()
+	{
+	return new(ELeave) CNwssTransLookUpTable::CNwssTransLUTEntry;
+	}
+
+CNwssTransLookUpTable::CNwssTransLUTEntry::CNwssTransLUTEntry()
+	{
+	}
+
+CNwssTransLookUpTable::CNwssTransLUTEntry::~CNwssTransLUTEntry()
+	{
+	delete iResponseBodyHandler;
+	}
+
+CNwssTransLookUpTable* CNwssTransLookUpTable::NewL(TInt aTableSize)
+	{
+	CNwssTransLookUpTable* me = new(ELeave)CNwssTransLookUpTable();
+	CleanupStack::PushL(me);
+	me->ConstructL(aTableSize);
+	CleanupStack::Pop(me);
+	return me;
+	}
+
+CNwssTransLookUpTable::CNwssTransLookUpTable()
+	{
+	}
+
+CNwssTransLookUpTable::~CNwssTransLookUpTable()
+	{
+	// Flush the look-up table.  Entries which are unused will delete OK since
+	// when removed, their iResponseBodyHandler pointer is reset to NULL.
+	iEntries.ResetAndDestroy();
+	}
+
+CNwssTransLookUpTable::CNwssTransLUTEntry& CNwssTransLookUpTable::NewEntry()
+	{
+	TInt numTableEntries = iEntries.Count();
+#ifdef __UNIT_TESTING__
+	if (numTableEntries == 0)
+		// dummy return for testing only
+		return *(REINTERPRET_CAST(CNwssTransLookUpTable::CNwssTransLUTEntry*, 1));
+#endif
+	__ASSERT_DEBUG(numTableEntries > 0, User::Invariant());
+
+	CNwssTransLookUpTable::CNwssTransLUTEntry* retVal = NULL;
+	if (iNumActiveLUTEntries < numTableEntries)
+		retVal = iEntries[iNumActiveLUTEntries++];
+#ifdef __UNIT_TESTING__
+	else
+		// dummy return for testing only
+		return *(REINTERPRET_CAST(CNwssTransLookUpTable::CNwssTransLUTEntry*, 1));
+#else
+	else
+		TNwssWspTrHndPanic::Panic(TNwssWspTrHndPanic::ETransLUTOverflow);
+#endif
+	return *retVal;
+	}
+
+CNwssTransLookUpTable::CNwssTransLUTEntry&
+CNwssTransLookUpTable::LookUpByTransId(RWSPCOTrans::TTransID aTransId, TBool& aFound)
+	{
+	// Iterate the look-up-table until we find the entry whose transaction ID matches
+	// the supplied value
+	aFound = EFalse;
+	TInt idx = 0;
+	while (!aFound && (idx < iNumActiveLUTEntries))
+		{
+		if (iEntries[idx]->iStackTransID == aTransId)
+			aFound = ETrue;
+		else
+			++idx;
+		}
+	if (aFound)
+		return *(iEntries[idx]);
+
+	// dummy return
+	CNwssTransLookUpTable::CNwssTransLUTEntry* retVal = NULL;
+	return *retVal;
+	}
+
+CNwssTransLookUpTable::CNwssTransLUTEntry&
+CNwssTransLookUpTable::LookUpByCallback(MWspCOMethodCallback& aCallback, TBool& aFound)
+	{
+	// Locate the item in the table
+	aFound = EFalse;
+	TInt unused = KErrNotFound;
+	CNwssTransLookUpTable::CNwssTransLUTEntry* lutEntry = LookUp(aCallback, unused);
+	if (lutEntry)
+		{
+		aFound = ETrue;
+		return *lutEntry;
+		}
+
+	// dummy return
+	CNwssTransLookUpTable::CNwssTransLUTEntry* retVal = NULL;
+	return *retVal;
+	}
+
+void CNwssTransLookUpTable::RemoveEntry(MWspCOMethodCallback& aCallback)
+	{
+	// Locate the item in the table
+	TInt idx = KErrNotFound;
+	CNwssTransLookUpTable::CNwssTransLUTEntry* lutEntry = LookUp(aCallback, idx);
+	if (lutEntry)
+		{
+		iEntries.Remove(idx);
+		--iNumActiveLUTEntries;
+
+		// Reset the entry, so it can be recycled
+		lutEntry->iCallback = NULL;
+		delete lutEntry->iResponseBodyHandler;
+		lutEntry->iResponseBodyHandler = NULL;
+		lutEntry->iStackTrans = RWSPCOTrans();
+		lutEntry->iStackTransID = 0;
+		lutEntry->iAborted = EFalse;
+
+		// Move the removed entry to the end of the table, to ensure the table remains
+		// of constant size.  Note, this append will not leave, since the table size
+		// was preallocated in ConstructL.
+#if defined (_DEBUG) && defined(__UNIT_TESTING__)
+		TInt err =
+#endif
+			iEntries.Append(lutEntry);
+#ifdef __UNIT_TESTING__
+		__ASSERT_DEBUG(err == KErrNone, 
+					TNwssWspTrHndPanic::Panic(TNwssWspTrHndPanic::ETransLUTOverflow));
+#endif
+		}
+	}
+
+TBool CNwssTransLookUpTable::IsEmpty() const
+	{
+	return iNumActiveLUTEntries == 0;
+	}
+
+CNwssTransLookUpTable::CNwssTransLUTEntry& CNwssTransLookUpTable::Head(TBool& aFound)
+	{
+	// Are there any entries
+	aFound = iNumActiveLUTEntries > 0;
+
+	// Return the first entry
+	if (aFound)
+		return *(iEntries[0]);
+
+	// dummy return
+	CNwssTransLookUpTable::CNwssTransLUTEntry* retVal = NULL;
+	return *retVal;
+	}
+
+void CNwssTransLookUpTable::ConstructL(TInt aTableSize)
+	{
+	CNwssTransLookUpTable::CNwssTransLUTEntry* entry;
+
+	// Pre-allocate the look-up table
+	for (TInt ii = 0; ii < aTableSize; ++ii)
+		{
+		entry = CNwssTransLookUpTable::CNwssTransLUTEntry::NewL();
+		CleanupStack::PushL(entry);
+		User::LeaveIfError(	iEntries.Append(entry) );
+		CleanupStack::Pop(entry);
+		}
+	}
+
+void CNwssTransLookUpTable::ResizeTableL(TInt aNewSize)
+	{
+	// Bail out now if the size doesn't change!
+	const TInt oldSize = iEntries.Count();
+	if (aNewSize == oldSize)
+		return;
+	CNwssTransLookUpTable::CNwssTransLUTEntry* entry = NULL;
+	if (aNewSize > oldSize)
+		{
+		// Table is being enlarged - pre-allocate new entries
+		for (TInt ii = 0; ii < (aNewSize - oldSize); ++ii)
+			{
+			entry = CNwssTransLookUpTable::CNwssTransLUTEntry::NewL();
+			CleanupStack::PushL(entry);
+			User::LeaveIfError(	iEntries.Append(entry) );
+			CleanupStack::Pop(entry);
+			}
+
+		// High-water mark doesn't change in this situation
+		}
+	else
+		{
+		// Table is being shrunk - remove surplus entries
+		for (TInt ii = oldSize - 1; ii >= aNewSize; --ii)
+			{
+			delete iEntries[ii];
+			iEntries.Remove(ii);
+			}
+
+		// Adjust high-water mark
+		if (iNumActiveLUTEntries > aNewSize)
+			iNumActiveLUTEntries = aNewSize;
+		}
+	}
+
+CNwssTransLookUpTable::CNwssTransLUTEntry*
+CNwssTransLookUpTable::LookUp(MWspCOMethodCallback& aCallback, TInt& aIndex)
+	{
+	// Iterate the look-up-table until we find the entry whose transaction callback
+	// matches the supplied value
+	TBool found = EFalse;
+	aIndex = 0;
+	CNwssTransLookUpTable::CNwssTransLUTEntry* lutEntry = NULL;
+	while (!found && (aIndex < iNumActiveLUTEntries))
+		{
+		lutEntry = iEntries[aIndex];
+		if (lutEntry->iCallback == &aCallback)
+			found = ETrue;
+		else
+			++aIndex;
+		}
+	if (!found)
+		{
+		aIndex = KErrNotFound;
+		lutEntry = NULL;
+		}
+	return lutEntry;
+	}