diff -r 000000000000 -r dfb7c4ff071f commsfwutils/commsbufs/src/commsbufq.cpp --- /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; + } +