commsfwutils/commsbufs/version1/mbufmgr/src/MB_QUE.CPP
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Buffer Manager for Protocols (MBuf and Packet Queues)
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include <es_mbman.h>
       
    24 
       
    25 //
       
    26 // MBUF QUEUE
       
    27 //
       
    28 
       
    29 __IMPLEMENT_CLEANUP(RMBufQ, Free)
       
    30 
       
    31 
       
    32 EXPORT_C RMBufQ::RMBufQ(RMBuf* aChain)
       
    33 /**
       
    34 Constructor initializes the members
       
    35 */
       
    36  	{
       
    37 	iNext = aChain;
       
    38 	iLast = aChain->Last(); // Safe even if aChain==NULL
       
    39 	}
       
    40 
       
    41 
       
    42 EXPORT_C void RMBufQ::Init()
       
    43 /**
       
    44 initializes the members
       
    45 */
       
    46 	{
       
    47 	iNext = NULL;
       
    48 	iLast = NULL;
       
    49 	}
       
    50 
       
    51 
       
    52 EXPORT_C void RMBufQ::Assign(RMBufQ& aQueue)
       
    53 /**
       
    54 Assign this queue to a MBuf queue
       
    55 @param aQueue to queue
       
    56 */
       
    57 	{
       
    58 	*this = aQueue;
       
    59 	aQueue.Init();
       
    60 	}
       
    61 
       
    62 
       
    63 EXPORT_C void RMBufQ::Assign(RMBufChain& aChain)
       
    64 /**
       
    65 Assign this a MBuf chain to this queue
       
    66 @param aChain the chain
       
    67 */
       
    68  	{
       
    69 	iNext = aChain.First();
       
    70 	iLast = aChain.Last();
       
    71 	aChain.Init();
       
    72 	}
       
    73 
       
    74 
       
    75 EXPORT_C void RMBufQ::Free()
       
    76 /**
       
    77 Frees the queue making it empty
       
    78 */
       
    79 	{
       
    80 	if(iNext)
       
    81 		iNext->Free();
       
    82 	Init();
       
    83 	}
       
    84 
       
    85 
       
    86 EXPORT_C void RMBufQ::Append(RMBuf* aBuf)
       
    87 /**
       
    88 Appends a MBuf to the queue
       
    89 @param aBuf the buffer to be prepended
       
    90 */
       
    91  	{
       
    92 	if (IsEmpty())
       
    93 		iNext = iLast = aBuf;
       
    94 	else
       
    95 		{
       
    96 		iLast->Link(aBuf);
       
    97 		iLast = aBuf;
       
    98 		}
       
    99 	}
       
   100 
       
   101 
       
   102 EXPORT_C void RMBufQ::Prepend(RMBuf* aBuf)
       
   103 /**
       
   104 Prepends one MBuf to this queue. aBuf must not point to any further Mbufs.
       
   105 @param aBuf the buffer to be appended
       
   106 */
       
   107 	{
       
   108 
       
   109     __ASSERT_DEBUG(aBuf->Next()==NULL, CMBufManager::Panic(EMBuf_CannotPrependChainedMBuf));
       
   110 	if (IsEmpty())
       
   111 		{
       
   112 		iNext = aBuf;
       
   113 		iLast = aBuf;
       
   114 		aBuf->Link(NULL);	// break the mbuf chain (if any)
       
   115 		}
       
   116 	else
       
   117 		{
       
   118 		aBuf->Link(iNext);	// alter the mbuf chain (if any)
       
   119 		iNext = aBuf;
       
   120 		}
       
   121 	}
       
   122 
       
   123 
       
   124 EXPORT_C void RMBufQ::Append(RMBufQ& aQueue)
       
   125 /**
       
   126 Appends a MBuf queue to this queue
       
   127 @param aQueue the queue to be appended
       
   128 */
       
   129  	{
       
   130 	if (aQueue.IsEmpty())
       
   131 		return;
       
   132 
       
   133 	if (IsEmpty())
       
   134 		{
       
   135 		// src queue is reset, thus this operation is an append & move
       
   136 		*this = aQueue;
       
   137 		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
       
   138 		}
       
   139 	else
       
   140 		{
       
   141 		// src queue is not altered, thus this operation is only an append (ie. no move)
       
   142 		iLast->Link(aQueue.iNext);
       
   143 		iLast = aQueue.iLast;
       
   144 		}
       
   145 	}
       
   146 
       
   147 
       
   148 EXPORT_C void RMBufQ::Append(RMBufChain& aChain)
       
   149 /**
       
   150 Appends a MBuf chain to this queue
       
   151 @param aChain the chain to be appended
       
   152 */
       
   153  	{
       
   154 	if (aChain.IsEmpty())
       
   155 		return;
       
   156 
       
   157 	if (IsEmpty())
       
   158 		iNext = aChain.First();
       
   159 	else
       
   160 		iLast->Link(aChain.First());
       
   161 	iLast = aChain.Last();
       
   162 	aChain.Init();
       
   163 	}
       
   164 
       
   165 
       
   166 EXPORT_C void RMBufQ::Prepend(RMBufChain& aChain)
       
   167 /**
       
   168 Prepends a MBuf chain to this queue
       
   169 @param aChain the chain to be prepended
       
   170 */
       
   171  	{
       
   172 	if (aChain.IsEmpty())
       
   173 		return;
       
   174 
       
   175 	if (IsEmpty())
       
   176 		iLast = aChain.Last();
       
   177 	else
       
   178 		aChain.Last()->Link(iNext);
       
   179 	iNext = aChain.First();
       
   180 	aChain.Init();
       
   181 	}
       
   182 
       
   183 
       
   184 EXPORT_C void RMBufQ::Prepend(RMBufQ& aQueue)
       
   185 /**
       
   186 Prepends a MBuf queue to this queue
       
   187 @param aQueue the queue to be prepended
       
   188 */
       
   189  	{
       
   190 	if (aQueue.IsEmpty())
       
   191 		return;
       
   192 
       
   193 	if (IsEmpty())
       
   194 		Assign(aQueue);
       
   195 	else
       
   196 		{
       
   197 		aQueue.iLast->Link(iNext);
       
   198 		iNext = aQueue.iNext;
       
   199 		}
       
   200 	}
       
   201 
       
   202 
       
   203 EXPORT_C RMBuf* RMBufQ::Remove()
       
   204 /**
       
   205 Removes the first MBuf from the queue
       
   206 @return the MBuf
       
   207 */
       
   208 	{
       
   209 	RMBuf* m;
       
   210 
       
   211 	if (IsEmpty())
       
   212 		return NULL;
       
   213 
       
   214 	m = iNext;
       
   215 
       
   216 	if (iNext = m->Next(), iNext==NULL)
       
   217 		iLast = NULL;
       
   218 
       
   219 	m->Unlink();
       
   220 
       
   221 	return m;
       
   222 	}
       
   223 
       
   224 TInt RMBufQ::Transfer(RMBufQ& aQueue, TInt aSize)
       
   225 /**
       
   226 For the benefit of the MBuf allocator
       
   227 Grab as many buffer as possible, as quickly as possible.
       
   228 @param aQueue the queue
       
   229 @param aSize the size
       
   230 @return aSize - buffer_space_transfered
       
   231 */
       
   232 	{
       
   233 	__ASSERT_DEBUG(aSize >= 0, CMBufManager::Panic(EMBuf_BadBufferSize));
       
   234 
       
   235 	TInt transfered = 0;
       
   236 	
       
   237 	if (!IsEmpty())
       
   238 		{
       
   239 		RMBuf* first;
       
   240 		RMBuf* next;
       
   241 		RMBuf* last;
       
   242 	
       
   243 		first = iNext;
       
   244 		next = first;
       
   245 		last = first;
       
   246 	
       
   247 		while (aSize >= 0 && next != NULL)
       
   248 			{
       
   249 			transfered += next->Size();
       
   250 			aSize -= next->Size();
       
   251 			last = next;
       
   252 			next = next->Next();
       
   253 			if (aSize == 0)
       
   254 				{
       
   255 				break;
       
   256 				}
       
   257 			}
       
   258 			
       
   259 		if (next)
       
   260 			{
       
   261 			last->Unlink();
       
   262 			iNext = next;
       
   263 			}
       
   264 		else
       
   265 			{
       
   266 			iNext = NULL;
       
   267 			iLast = NULL;
       
   268 			}
       
   269 
       
   270 		RMBufQ q(first, last);
       
   271 		
       
   272 		if (aSize < 0)
       
   273 			{
       
   274 			q.First()->AdjustEnd(aSize);
       
   275 			}
       
   276 		aQueue.Prepend(q);
       
   277 		}
       
   278 	return transfered;
       
   279 	}
       
   280 
       
   281 
       
   282 //
       
   283 // MBUF PACKET QUEUE
       
   284 //
       
   285 
       
   286 __IMPLEMENT_CLEANUP(RMBufPktQ, Free)
       
   287 
       
   288 
       
   289 EXPORT_C void RMBufPktQ::Init()
       
   290 /**
       
   291 Initializes the the members
       
   292 */
       
   293 	{
       
   294 	iNext.Init();
       
   295 	iLast.Init();
       
   296 	}
       
   297 
       
   298 
       
   299 EXPORT_C void RMBufPktQ::Free()
       
   300 /**
       
   301 Frees the RMBuf Paket Queue, delets all objects
       
   302 */
       
   303 	{
       
   304 	RMBufChain chain;
       
   305 	while (Remove(chain))
       
   306 		chain.Free();
       
   307 	}
       
   308 
       
   309 
       
   310 EXPORT_C void RMBufPktQ::Append(RMBufChain& aChain)
       
   311 /**
       
   312 Appends a MBuf chain to the queue
       
   313 @param aCHain A MBuf Chain
       
   314 */
       
   315  	{
       
   316 	if (IsEmpty())
       
   317 		{
       
   318 		iNext = aChain;
       
   319 		iLast = aChain;
       
   320 		}
       
   321 	else
       
   322 		{
       
   323 		iLast.Link(aChain);
       
   324 		iLast = aChain;
       
   325 		}
       
   326 	aChain.Init();
       
   327 	}
       
   328 
       
   329 
       
   330 EXPORT_C void RMBufPktQ::Append(RMBufPktQ& aQueue)
       
   331 /**
       
   332 Appends a queue to the queue
       
   333 @param aQueue a BMuf Paket Queue
       
   334 */
       
   335  	{
       
   336 	if (aQueue.IsEmpty())
       
   337 		return;
       
   338 
       
   339 	if (IsEmpty())
       
   340 		{
       
   341 		iNext = aQueue.iNext;
       
   342 		iLast = aQueue.iLast;
       
   343 		}
       
   344 	else
       
   345 		{
       
   346 		iLast.Link(aQueue.iNext);
       
   347 		iLast = aQueue.iLast;
       
   348 		}
       
   349 	aQueue.Init();
       
   350 	}
       
   351 
       
   352 
       
   353 EXPORT_C void RMBufPktQ::Prepend(RMBufChain& aChain)
       
   354 /**
       
   355 Prepends a MBuf chain to the queue
       
   356 @param aCHain A MBuf Chain
       
   357 */
       
   358  	{
       
   359 	if (IsEmpty())
       
   360 		{
       
   361 		iNext = aChain;
       
   362 		iLast = aChain;
       
   363 		}
       
   364 	else
       
   365 		{
       
   366 		aChain.Link(iNext);
       
   367 		iNext = aChain;
       
   368 		}
       
   369 	aChain.Init();
       
   370 	}
       
   371 
       
   372 
       
   373 EXPORT_C TBool RMBufPktQ::Remove(RMBufChain& aChain)
       
   374 /**
       
   375 Prepends a queue to the queue
       
   376 @param aQueue a BMuf Packet Queue
       
   377 */
       
   378 	{
       
   379 	if (IsEmpty())
       
   380 		return EFalse;
       
   381 
       
   382 	aChain = iNext;
       
   383 
       
   384 	if (iNext = iNext.Next(), iNext.IsEmpty())
       
   385 		iLast.Init();
       
   386 
       
   387 	aChain.Unlink();
       
   388 	return ETrue;
       
   389 	}
       
   390 
       
   391 
       
   392 void RMBufPktQ::Insert(RMBufChain& aNew, RMBufChain& aPrev)
       
   393 /**
       
   394 Inserts a MBuf chain next to a member in the queue
       
   395 @param aNew A MBuf chain to be inserted
       
   396 @param aPrev the member (a RMBufChain object) of the chain next to which the chain in inserted into
       
   397 */
       
   398 	{
       
   399 	if (aPrev.IsEmpty())
       
   400 		Prepend(aNew);
       
   401 	else if (aPrev.Next().IsEmpty())
       
   402  		Append(aNew);
       
   403 	else
       
   404 		{
       
   405 		RMBufChain tmp;
       
   406 		tmp.Assign(aNew);
       
   407 		tmp.Link(aPrev.Next());
       
   408 		aPrev.Link(tmp);
       
   409 		}
       
   410 	}
       
   411 
       
   412 void RMBufPktQ::Remove(RMBufChain& aNew, RMBufChain& aPrev)
       
   413 /**
       
   414 Removes the part after a member from the queue
       
   415 @param aNew the resulted removed part
       
   416 @param aPrevious the memeber (a RMBufChain object) of the chain the part of which is removed from the queue
       
   417 */
       
   418 	{
       
   419 	if (aPrev.IsEmpty())
       
   420 		Remove(aNew);
       
   421 	else
       
   422 		{
       
   423 		aNew.Assign(aPrev.Next());
       
   424 		aPrev.Link(aNew.Next());
       
   425 		aNew.Unlink();
       
   426 		}
       
   427 	}
       
   428 
       
   429 EXPORT_C void TMBufPktQIter::Insert(RMBufChain& aNewChain)
       
   430 /**
       
   431 Inserts a chain into the queue to the part after current position
       
   432 @param aNewChain the chain to be inserted
       
   433 */
       
   434 	{
       
   435 	iQueue->Insert(aNewChain, iPrev);
       
   436 	TidyAfterUpdate();
       
   437 	}
       
   438 
       
   439 EXPORT_C void TMBufPktQIter::Remove(RMBufChain& aNewChain)
       
   440 /**
       
   441 Removes the part after the current position
       
   442 @param aNewChain the resulted removed queue
       
   443 */
       
   444 	{
       
   445 	iQueue->Remove(aNewChain, iPrev);
       
   446 	TidyAfterUpdate();
       
   447 	}
       
   448 
       
   449 EXPORT_C const RMBufChain& TMBufPktQIter::operator ++(TInt)
       
   450 /**
       
   451 Operator ++
       
   452 move to the next position in the queue
       
   453 */
       
   454 	{
       
   455 	if (iPrev = iCurrent, !iPrev.IsEmpty())
       
   456 		iCurrent = iPrev.Next();
       
   457 	return iPrev;
       
   458 	}
       
   459 
       
   460 EXPORT_C void TMBufPktQIter::TidyAfterUpdate()
       
   461 /**
       
   462 Update the current position, after update
       
   463 if the current position becomes empty after update - the current position will
       
   464 be the first in the queue, else the next in the queue
       
   465 */
       
   466 	{
       
   467 	if (iPrev.IsEmpty())
       
   468 		SetToFirst();
       
   469 	else
       
   470 		iCurrent = iPrev.Next();
       
   471 	}