--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwutils/commsbufs/version1/mbufmgr/src/MB_PKT.CPP Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,413 @@
+// Copyright (c) 1997-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:
+// MBuf Packet Info Headers
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <nifmbuf.h>
+
+
+//
+// MBuf Manager Extensions
+//
+
+__IMPLEMENT_CLEANUP(RMBufPacketBase, Free)
+
+EXPORT_C RMBufPacketBase::RMBufPacketBase()
+/**
+Constructor
+*/
+ {
+ iInfo=NULL;
+ }
+
+EXPORT_C void RMBufPacketBase::CopyInfoL(RMBufPacketBase& aNewPkt)
+/**
+Copy the information header
+@param aNewPkt the new packet where the header is copied to
+*/
+ {
+ aNewPkt.iInfo = (RMBufPktInfo*)iInfo->CopyL();
+ }
+
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::PeekInfo()
+/**
+Allows the packet info header to be accessed without unpacking
+@return the packet info header
+*/
+ {
+ __ASSERT_DEBUG(iInfo==NULL, MBufExtPanic(EMbExtPanic_PacketHeader));
+ __ASSERT_ALWAYS(!IsEmpty(), MBufExtPanic(EMbExtPanic_PacketHeaderEmpty));
+ __ASSERT_ALWAYS(First()->Type()==EMBufHeader, MBufExtPanic(EMbExtPanic_PacketHeader));
+ return (RMBufPktInfo*)(First()->Ptr());
+ }
+
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::Unpack()
+/**
+Splits off the info header
+@return the packet info header
+*/
+ {
+ __ASSERT_DEBUG(iInfo==NULL, MBufExtPanic(EMbExtPanic_PacketHeader));
+ __ASSERT_ALWAYS(!IsEmpty(), MBufExtPanic(EMbExtPanic_PacketHeaderEmpty));
+ __ASSERT_ALWAYS(First()->Type()==EMBufHeader, MBufExtPanic(EMbExtPanic_PacketHeader));
+ iInfo = (RMBufPktInfo*)(Remove()->Ptr());
+ return Info();
+ }
+
+
+EXPORT_C void RMBufPacketBase::Pack()
+/**
+Combine info header with data ready for queueing
+*/
+ {
+ __ASSERT_ALWAYS(iInfo!=NULL, MBufExtPanic(EMbExtPanic_PacketHeader));
+ Prepend(iInfo->MBuf());
+ iInfo = NULL;
+ }
+
+
+EXPORT_C void RMBufPacketBase::SetInfo(RMBufPktInfo* aInfo)
+/**
+Associate an info header with packet
+(Also used to disassociate if aInfo==NULL)
+@param aInfo the info header
+*/
+ {
+ iInfo = aInfo;
+ }
+
+
+EXPORT_C void RMBufPacketBase::FreeInfo()
+/**
+Free info header only
+*/
+ {
+ if (iInfo)
+ {
+ iInfo->MBuf()->Free();
+ iInfo = NULL;
+ }
+ }
+
+EXPORT_C void RMBufPacketBase::Free()
+/**
+Delete info and data
+*/
+ {
+ FreeInfo();
+ RMBufChain::Free();
+ }
+
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::Info()
+/**
+Returns pointer to info header
+@return the info header
+*/
+ {
+ __ASSERT_ALWAYS(iInfo!=NULL, MBufExtPanic(EMbExtPanic_PacketHeader));
+ return (RMBufPktInfo*)iInfo;
+ }
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::CreateL(RMBufQ& aPacket, TInt aLength, TUint aMBufHdrSize)
+/**
+Create an MBuf chain from an received MBuf Queue
+ - used by Interfaces
+ - queue in emptied.
+@param aPacket the MBuf Queue
+@param aLength the chain length
+@param aMBufHdrSize the MBuf header size
+@return the info header
+*/
+ {
+ iInfo = new (ELeave, aMBufHdrSize-sizeof(RMBufPktInfo)) RMBufPktInfo;
+ Assign(aPacket);
+ iInfo->iLength = aLength==0 ? Length() : aLength;
+ return (RMBufPktInfo*)iInfo;
+ }
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::CreateL(TInt aLength, TUint aMBufHdrSize)
+/**
+Create an empty MBuf chain of required length and header size
+ - used by Interfaces
+ - refer RMBufChain::AllocL notes regarding the deliberate decision not to provide an overloaded min/max mbuf size variant
+@param aLength the chain length
+@param aMBufHdrSize the header size
+@return the info header
+*/
+ {
+ RMBufChain::AllocL(aLength);
+ CleanupStack::PushL(*this);
+ iInfo = new (ELeave, aMBufHdrSize-sizeof(RMBufPktInfo)) RMBufPktInfo;
+ CleanupStack::Pop();
+ iInfo->iLength = aLength;
+ return (RMBufPktInfo*)iInfo;
+ }
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::CreateL(const TDesC8 &aDesc, TInt aHdrSize, TUint aMBufHdrSize)
+/**
+Create a MBuf chain and header for receiving from a descriptor
+ - used by SAPs
+@param aDesc the buffer which contains the header info
+@param aHdrSize the header size
+@param aMBufHdrSize the MBuf header size
+@return the info header
+*/
+ {
+ RMBufChain::CreateL(aDesc, aHdrSize);
+ CleanupStack::PushL(*this);
+ iInfo = new (ELeave, aMBufHdrSize-sizeof(RMBufPktInfo)) RMBufPktInfo;
+ CleanupStack::Pop();
+ iInfo->iLength = aDesc.Length()+aHdrSize;
+ return (RMBufPktInfo*)iInfo;
+ }
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::CreateCopyL(const RMBufQ& aPacket, TInt aOffset, TInt aLength, TInt aHdrSize, TUint aMBufHdrSize)
+/**
+Create a MBuf chain from an received MBuf Queue
+ - used by Interfaces
+@param aPacket the MBuf Queue
+@param aOffset the offset
+@param aLength the length of the data to be copied
+@param aHdrSize the header size
+@param aMBufHdrSize the MBuf Header Size
+@return the info header
+*/
+ {
+ iInfo = new (ELeave, aMBufHdrSize-sizeof(RMBufPktInfo)) RMBufPktInfo;
+ iInfo->iLength = (aLength==0 ? Length() : aLength) + aHdrSize;
+ ((RMBufChain&)aPacket).CopyL(*this, aOffset, aLength);
+ PrependL(aHdrSize);
+ return (RMBufPktInfo*)iInfo;
+ }
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::CreateCopyL(RMBufStreamQ& aStream, TInt aOffset, TInt aLength, TInt aHdrSize, TUint aMBufHdrSize)
+/**
+Create a MBuf chain by copying data from a stream queue (basically an RMBufQ)
+aOffset and aLength specify location in stream queue.
+@param aStream the stream queue
+@param aOffset the offset
+@param aLength the data length
+@param aHdrSize the header size
+@param aMBufHdrSize the MBuf Header size
+@return the info header
+*/
+ {
+ iInfo = new (ELeave, aMBufHdrSize-sizeof(RMBufPktInfo)) RMBufPktInfo;
+ iInfo->iLength = (aLength==0 ? Length() : aLength) + aHdrSize;
+ aStream.CopySegmentL(*this, aOffset, aLength);
+ PrependL(aHdrSize);
+ return (RMBufPktInfo*)iInfo;
+ }
+
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::CreateCopyL(const RMBufPktQ& aList, TInt aHdrSize, TUint aMBufHdrSize)
+/**
+Build a MBuf chain by copying a packet queue list, leaving space on the front
+for a header. (Very heavily used in PPP option processing).
+This is specially coded rather than using combination of RMBufChain::CopyL
+and RMBufChain::AppendL to ensure that the resulting packet is stored efficiently.
+- refer RMBufChain::AllocL notes regarding the deliberate decision not to provide an overloaded min/max mbuf size variant
+@param aList the packet queue
+@param aHdrSize the header size
+@param aMBufHdrSize the MBuf Header size
+@return the info header
+*/
+ {
+ // min K_MBufSmallSize sized mbuf is a valid assumption, because all headers are assumed to derive from a cell, which in turn is size K_MBufSmallSize
+ __ASSERT_ALWAYS(aHdrSize<KMBufSmallSize, MBufExtPanic(EMbExtPanic_HeaderTooBig));
+
+ iInfo = new (ELeave, aMBufHdrSize-sizeof(RMBufPktInfo)) RMBufPktInfo;
+
+ RMBufChain i;
+
+ // Get total length of chain needed
+ TInt len = 0;
+ i = aList.First();
+ while (!i.IsEmpty())
+ {
+ len += i.Length();
+ i = i.Next();
+ }
+
+ // Allocate the chain
+ iInfo->iLength = len+aHdrSize;
+ AllocL(iInfo->iLength);
+
+ // Do the copy
+ TInt n, n1, n2;
+ TUint8* p1, * p2;
+ RMBuf* m1, * m2;
+
+ i = aList.First();
+ m1 = i.First();
+ p1 = m1->Ptr();
+ n1 = m1->Length();
+
+ m2 = First();
+ p2 = m2->Ptr();
+ n2 = m2->Length();
+
+ if (aHdrSize>0)
+ {
+ if (aHdrSize==KMBufSmallSize) // min K_MBufSmallSize sized mbuf is a valid assumption, because all headers are assumed to derive from a cell, which in turn is size K_MBufSmallSize
+ {
+ m2 = m2->Next();
+ p2 = m2->Ptr();
+ n2 = m2->Length();
+ }
+ else
+ {
+ p2 += aHdrSize;
+ n2 -= aHdrSize;
+ }
+ }
+
+ while (len>0)
+ {
+ n = n1<n2 ? n1 : n2;
+ Mem::Copy(p2, p1, n);
+ if (n1 -= n, n1==0)
+ {
+ if (m1 = m1->Next(), m1==NULL)
+ {
+ i = i.Next();
+ m1 = i.First();
+ }
+ p1 = m1->Ptr();
+ n1 = m1->Length();
+ }
+ else
+ p1 += n;
+ if (n2 -= n, n2==0)
+ {
+ m2 = m2->Next();
+ p2 = m2->Ptr();
+ n2 = m2->Length();
+ }
+ else
+ p2 += n;
+ len -= n;
+ }
+
+ return (RMBufPktInfo*)iInfo;
+ }
+
+
+EXPORT_C void RMBufPacketBase::TrimStart(TInt aOffset)
+/**
+As RMBufChain::TrimStart, but updates length in info header
+@param aOffset the offset
+*/
+ {
+ RMBufChain::TrimStart(aOffset);
+ iInfo->iLength -= aOffset;
+ }
+
+
+EXPORT_C void RMBufPacketBase::TrimEnd(TInt aOffset)
+/**
+As RMBufChain::TrimEnd, but updates length in info header
+@param aOffset the offset
+*/
+ {
+// !BUG! Work around
+ if (aOffset==0)
+ RMBufChain::Free();
+ else
+// End work-around
+ RMBufChain::TrimEnd(aOffset);
+ iInfo->iLength = aOffset;
+ }
+
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::NewInfoL(TUint aMBufHdrSize)
+/**
+Create an info header
+@param aMBufHdrSize the MBuf header size
+@return the info header
+*/
+ {
+ iInfo = new (ELeave, aMBufHdrSize-sizeof(RMBufPktInfo)) RMBufPktInfo;
+ return (RMBufPktInfo*)iInfo;
+ }
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::NewInfo(TUint aMBufHdrSize)
+/**
+Create an info header
+@param aMBufHdrSize the MBuf header size
+@return the info header
+*/
+ {
+ iInfo = new (aMBufHdrSize-sizeof(RMBufPktInfo)) RMBufPktInfo;
+ return (RMBufPktInfo*)iInfo;
+ }
+
+EXPORT_C void RMBufPacketBase::CopyPackedL(RMBufChain& aPacket)
+/**
+Copy an entire packed packet, complete with info header
+@param aPacket the packet
+*/
+ {
+ __ASSERT_DEBUG(iInfo==NULL, MBufExtPanic(EMbExtPanic_PacketHeader));
+ __ASSERT_ALWAYS(!aPacket.IsEmpty(), MBufExtPanic(EMbExtPanic_PacketHeaderEmpty));
+ __ASSERT_ALWAYS(aPacket.First()->Type()==EMBufHeader, MBufExtPanic(EMbExtPanic_PacketHeader));
+ RMBuf* m = aPacket.Remove();
+ //
+ // The following assumes that aPacket.CopyL would actually leave before it makes any change
+ // to aPacket at all. Inspection of CopyL reveals that this is the case.
+ //
+ TRAPD(err, aPacket.CopyL(*this));
+ //
+ // In case CopyL failed, we'd need to restore aPacket, so we'd call Prepend.
+ // In case it succedded, we'd still need to call Prepend so that the info block remains the same.
+ // Hence we call aPacket.Prepend irrespective of aPacket.CopyL failure.
+ //
+ aPacket.Prepend(m);
+ User::LeaveIfError(err);
+
+ RMBufPktInfo* info = (RMBufPktInfo*)((RMBufPktInfo*)(m->Ptr()))->CopyL();
+ Prepend(info->MBuf());
+ }
+
+EXPORT_C RMBufPktInfo* RMBufPacketBase::PeekInfoInChain(RMBufChain& aChain)
+/**
+Allows the packet info header to be accessed while still on a packet queue
+@param aChain the chain to be accessed
+@return the info header
+*/
+ {
+ __ASSERT_ALWAYS(!aChain.IsEmpty(), MBufExtPanic(EMbExtPanic_PacketHeaderEmpty));
+ __ASSERT_ALWAYS(aChain.First()->Type()==EMBufHeader, MBufExtPanic(EMbExtPanic_PacketHeader));
+ return (RMBufPktInfo*)(aChain.First()->Ptr());
+ }
+
+void MBufExtPanic(TMBufExtPanic aPanic)
+/**
+extra panic function that causes panic
+@param panic code
+*/
+ {
+ _LIT(mBufExtString,"MBufExt");
+ User::Panic(mBufExtString, aPanic);
+ }
+