--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwutils/commsbufs/src/commsbufq.cpp Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,276 @@
+// Copyright (c) 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 "es_commsbuf_internal.h"
+
+__IMPLEMENT_CLEANUP(RCommsBufQ, Free)
+
+
+EXPORT_C RCommsBufQ::RCommsBufQ(RCommsBuf* aChain)
+ {
+ iNext = aChain;
+ iLast = RCommsBufChain(aChain).Last(); // Safe even if aChain==NULL
+ }
+
+
+EXPORT_C void RCommsBufQ::Init()
+/**
+initializes the members
+*/
+ {
+ iNext = NULL;
+ iLast = NULL;
+ }
+
+
+EXPORT_C void RCommsBufQ::Assign(RCommsBufQ& aQueue)
+/**
+Assign this queue to a RCommsBuf queue
+@param aQueue to queue
+*/
+ {
+ *this = aQueue;
+ aQueue.Init();
+ }
+
+
+EXPORT_C void RCommsBufQ::Assign(RCommsBufChain& aChain)
+/**
+Assign this a RCommsBuf chain to this queue
+@param aChain the chain
+*/
+ {
+ iNext = aChain.First();
+ iLast = aChain.Last();
+ aChain.iNext = NULL;
+ }
+
+
+EXPORT_C void RCommsBufQ::Free()
+/**
+Frees the queue making it empty
+*/
+ {
+ if(iNext)
+ iNext->Free();
+ Init();
+ }
+
+
+EXPORT_C void RCommsBufQ::Append(RCommsBuf* aBuf)
+/**
+Appends a RCommsBuf to the queue
+@param aBuf the buffer to be prepended
+*/
+ {
+ if (IsEmpty())
+ iNext = iLast = aBuf;
+ else
+ {
+ iLast->SetNext(aBuf);
+ iLast = aBuf;
+ }
+ }
+
+
+EXPORT_C void RCommsBufQ::Prepend(RCommsBuf* aBuf)
+/**
+Prepends one RCommsBuf to this queue. aBuf must not point to any further CommsBufs.
+@param aBuf the buffer to be appended
+*/
+ {
+
+ __ASSERT_DEBUG(aBuf->Next()==NULL, CommsBuf::Panic(EMBuf_CannotPrependChainedMBuf));
+ if (IsEmpty())
+ {
+ iNext = aBuf;
+ iLast = aBuf;
+ aBuf->SetNext(NULL); // break the mbuf chain (if any)
+ }
+ else
+ {
+ aBuf->SetNext(iNext); // alter the mbuf chain (if any)
+ iNext = aBuf;
+ }
+ }
+
+
+EXPORT_C void RCommsBufQ::Append(RCommsBufQ& aQueue)
+/**
+Appends a RCommsBuf queue to this queue
+@param aQueue the queue to be appended
+*/
+ {
+ if (aQueue.IsEmpty())
+ return;
+
+ if (IsEmpty())
+ {
+ // src queue is reset, thus this operation is an append & move
+ *this = aQueue;
+ aQueue.Init(); // trs; why zero the src queue? implies a move instead of just append. ideally this should be fixed, but kept as is to avoid a functional break
+ }
+ else
+ {
+ // src queue is not altered, thus this operation is only an append (ie. no move)
+ iLast->SetNext(aQueue.iNext);
+ iLast = aQueue.iLast;
+ }
+ }
+
+
+EXPORT_C void RCommsBufQ::Append(RCommsBufChain& aChain)
+/**
+Appends a RCommsBuf chain to this queue
+@param aChain the chain to be appended
+*/
+ {
+ if (aChain.IsEmpty())
+ return;
+
+ if (IsEmpty())
+ iNext = aChain.First();
+ else
+ iLast->SetNext(aChain.First());
+ iLast = aChain.Last();
+ aChain.iNext = NULL;
+ }
+
+
+EXPORT_C void RCommsBufQ::Prepend(RCommsBufChain& aChain)
+/**
+Prepends a RCommsBuf chain to this queue
+@param aChain the chain to be prepended
+*/
+ {
+ if (aChain.IsEmpty())
+ return;
+
+ if (IsEmpty())
+ iLast = aChain.Last();
+ else
+ aChain.Last()->SetNext(iNext);
+ iNext = aChain.First();
+ aChain.iNext = NULL;
+ }
+
+
+EXPORT_C void RCommsBufQ::Prepend(RCommsBufQ& aQueue)
+/**
+Prepends a RCommsBuf queue to this queue
+@param aQueue the queue to be prepended
+*/
+ {
+ if (aQueue.IsEmpty())
+ return;
+
+ if (IsEmpty())
+ Assign(aQueue);
+ else
+ {
+ aQueue.iLast->SetNext(iNext);
+ iNext = aQueue.iNext;
+ }
+ }
+
+
+EXPORT_C RCommsBuf* RCommsBufQ::Remove()
+/**
+Removes the first RCommsBuf from the queue
+@return the MBuf
+*/
+ {
+ RCommsBuf* m;
+
+ if (IsEmpty())
+ return NULL;
+
+ m = iNext;
+
+ if (iNext = m->Next(), iNext==NULL)
+ iLast = NULL;
+
+ m->SetNext(NULL);
+
+ return m;
+ }
+
+EXPORT_C TInt RCommsBufQ::Transfer(RCommsBufQ& aQueue, TInt aSize, TInt aBufSize, TInt& aCount)
+ {
+ __ASSERT_DEBUG(aSize >= 0, CommsBuf::Panic(EMBuf_BadBufferSize));
+
+ TInt transfered = 0;
+ aCount = 0;
+
+ if (!IsEmpty())
+ {
+ RCommsBuf* first;
+ RCommsBuf* next;
+ RCommsBuf* last;
+
+ first = iNext;
+ next = first;
+ last = first;
+
+ do
+ {
+ ++aCount;
+ transfered += aBufSize;
+ aSize -= aBufSize;
+ last = next;
+ next = next->Next();
+ } while (aSize > 0 && next != NULL);
+
+ if (next)
+ {
+ last->SetNext(NULL);
+ iNext = next;
+ }
+ else
+ {
+ iNext = NULL;
+ iLast = NULL;
+ }
+
+ RCommsBufQ q(first, last);
+
+ if (aSize < 0)
+ {
+ q.Last()->AdjustDataEnd(aSize);
+ }
+ aQueue.Append(q);
+ }
+ return transfered;
+ }
+
+EXPORT_C RCommsBuf* RCommsBufQ::RemoveLast()
+ {
+ RCommsBuf* current = iNext;
+ if(iNext == iLast)
+ {
+ iNext = iLast = NULL;
+ return current;
+ }
+
+ while(current->Next() != iLast)
+ {
+ current = current->Next();
+ }
+ RCommsBuf* last = iLast;
+ current->SetNext(NULL);
+ iLast = current;
+ return last;
+ }
+