commsfwutils/commsbufs/mbufmgr/src/mb_chn.cpp
changeset 0 dfb7c4ff071f
child 18 9644881fedd0
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 Chains)
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <es_mbuf.h>
       
    19 #include <cflog.h>
       
    20 #include "commsbufpondintf.h"
       
    21 #include "commsbufpool.h"
       
    22 //
       
    23 // MBUF CHAIN
       
    24 //
       
    25 
       
    26 __IMPLEMENT_CLEANUP(RMBufChain, Free)
       
    27 
       
    28 
       
    29 EXPORT_C void RMBufChain::AllocL(TInt aLen)
       
    30 /**
       
    31 Allocate sufficient mbufs to hold specfied amount of data
       
    32 
       
    33 - Overloaded min/max variants (eg. refer RMBufChain::Alloc) deliberately do not exist because;
       
    34   a. Intention is to ultimately deprecate (or at least discourage) the leaving variants since their usage is not typically (but not always
       
    35      the case) recommended because they the throw/catch mechanism can hinder performance if used in appopriately.
       
    36   b. Intention is to ultimately deprecate (or at least discourage) this class as it will likely be superceded by a generic system wide
       
    37      equivalent.
       
    38   c. If they shown to useful for this API, they can easily be added in the future... but the same can not be said for removing them in the future!
       
    39 @param aLen A length of the cell
       
    40 */
       
    41 	{
       
    42 	RMBufAllocator allocator;
       
    43 	User::LeaveIfError(RCommsBufChain::Alloc(aLen, allocator));
       
    44 	}
       
    45 
       
    46 EXPORT_C TInt RMBufChain::Alloc(TInt aLen)
       
    47 /**
       
    48 Allocate sufficient mbufs to hold specfied amount of data
       
    49 
       
    50 @param aLen A length of the cell
       
    51 */
       
    52 	{
       
    53 	RMBufAllocator allocator;	
       
    54 	return RCommsBufChain::Alloc(aLen, allocator);
       
    55 	}
       
    56 
       
    57 TInt RMBufChain::Alloc(TInt aLen, const RMBufChain &aMBufChain)
       
    58 /**
       
    59 Allocate sufficient mbufs to hold specfied amount of data
       
    60 
       
    61 @param aLen A length of the cell
       
    62 
       
    63 @return KErrNone if allocation is success 
       
    64 @return KErrNoMBufs if allocation is failed
       
    65 */
       
    66 	{	
       
    67 	if(aMBufChain.First())
       
    68 		{
       
    69 		const RCommsBuf* commsBuf = static_cast<const RCommsBuf*>(aMBufChain.First());
       
    70 		iNext = commsBuf->Pool()->Pond().Alloc(aLen, commsBuf->RawSize(), commsBuf->RawSize());
       
    71 		return iNext ? KErrNone : KErrNoMBufs;		
       
    72 		}
       
    73 	RMBufAllocator allocator;
       
    74 	return RCommsBufChain::Alloc(aLen, allocator);	
       
    75 	}
       
    76 	
       
    77 EXPORT_C TInt RMBufChain::Alloc(TInt aLen, TInt aMinMBufSize)
       
    78 	{
       
    79 	RMBufAllocator allocator;
       
    80 	return RCommsBufChain::Alloc(aLen, aMinMBufSize, allocator);
       
    81 	}
       
    82 	
       
    83 EXPORT_C TInt RMBufChain::Alloc(TInt aLen, TInt aMinMBufSize, TInt aMaxMBufSize)
       
    84 	{
       
    85 	RMBufAllocator allocator;
       
    86 	return RCommsBufChain::Alloc(aLen, aMinMBufSize, aMaxMBufSize, allocator);
       
    87 	}
       
    88 
       
    89 
       
    90 // overloading for TLS
       
    91 EXPORT_C void RMBufChain::AllocL(TInt aLen, RMBufAllocator& aRMBufAllocator)
       
    92 	{
       
    93 	User::LeaveIfError(RCommsBufChain::Alloc(aLen, aRMBufAllocator));
       
    94 	}
       
    95 	
       
    96 EXPORT_C TInt RMBufChain::Alloc(TInt aLen, RMBufAllocator& aRMBufAllocator)
       
    97 	{
       
    98 	return RCommsBufChain::Alloc(aLen, aRMBufAllocator);
       
    99 	}
       
   100 	
       
   101 TInt RMBufChain::Alloc(TInt aLen, const RMBufChain& aMBufChain, RMBufAllocator& aRMBufAllocator)
       
   102 	{
       
   103 	if(aMBufChain.First())
       
   104 		{
       
   105 		return RCommsBufChain::Alloc(aLen, aMBufChain.First ()->Size(), aMBufChain.First ()->Size(), aRMBufAllocator);			
       
   106 		}
       
   107 	else
       
   108 		{
       
   109 		return RCommsBufChain::Alloc(aLen, aLen, aRMBufAllocator);	
       
   110 		}		
       
   111 	}
       
   112 	
       
   113 EXPORT_C TInt RMBufChain::Alloc(TInt aLen, TInt aMinMBufSize, RMBufAllocator& aRMBufAllocator)
       
   114 	{
       
   115 	return RCommsBufChain::Alloc(aLen, aMinMBufSize, aRMBufAllocator);
       
   116 	}
       
   117 	
       
   118 EXPORT_C TInt RMBufChain::Alloc(TInt aLen, TInt aMinMBufSize, TInt aMaxMBufSize, RMBufAllocator& aRMBufAllocator)
       
   119 	{
       
   120 	return RCommsBufChain::Alloc(aLen, aMinMBufSize, aMaxMBufSize, aRMBufAllocator);
       
   121 	}
       
   122 
       
   123 EXPORT_C TInt RMBufChain::ReAlloc(TInt aLen)
       
   124 /**
       
   125 Adjust the size of a chain, allocates a new memory for the chain
       
   126 - refer RMBufChain::AllocL notes regarding the deliberate decision not to provide an overloaded min/max mbuf size variant
       
   127 @param aLen A new length
       
   128 */
       
   129 	{
       
   130 	__ASSERT_ALWAYS(aLen>=0, CommsBuf::Panic(EMBuf_NegativeLength));
       
   131 
       
   132 	TInt currLen = Length();
       
   133 	if(aLen < currLen)
       
   134 		{
       
   135 		TrimEnd(aLen);			
       
   136 		}
       
   137 	else if(aLen > currLen)
       
   138 		{
       
   139 		TInt extraReq = aLen - currLen;
       
   140 		if(currLen > 0)
       
   141 			{
       
   142 			// Extend the final buf to consume any idle space
       
   143 			RMBuf* pLast = static_cast<RMBuf*>(Last());
       
   144 			TInt idleSpace = pLast->Size() - pLast->End();
       
   145 			ASSERT(idleSpace >= 0);
       
   146 			if(idleSpace)
       
   147 				{
       
   148 				TInt useSpace = Min(idleSpace, extraReq);
       
   149 				pLast->AdjustEnd(useSpace);
       
   150 				extraReq -= useSpace;
       
   151 				// Did this yield enough?
       
   152 				if(!extraReq)
       
   153 					{
       
   154 					return KErrNone;						
       
   155 					}
       
   156 				}
       
   157 			}
       
   158 		// Need additional allocation
       
   159 		RMBufChain extraChain;
       
   160 		TInt err = extraChain.Alloc(extraReq, *this);
       
   161 		if(err != KErrNone)
       
   162 			{
       
   163 			return err;
       
   164 			}
       
   165 		RCommsBufChain::Append(extraChain);
       
   166 		}
       
   167 	return KErrNone;
       
   168 	}
       
   169 
       
   170 EXPORT_C void RMBufChain::ReAllocL(TInt aLen)
       
   171 /**
       
   172 Adjust the size of a chain, allocates a new memory for the chain
       
   173 @param aLen A new length
       
   174 */
       
   175 	{
       
   176 	User::LeaveIfError(ReAlloc(aLen));
       
   177 	}
       
   178 
       
   179 
       
   180 
       
   181 EXPORT_C TInt RMBufChain::Create(const TDesC8& aDes, TInt aHdrLen)
       
   182 /**
       
   183 Create an Mbuf chain from a descriptor optionally allowing room at front for a protocol header.
       
   184 - refer RMBufChain::AllocL notes regarding the deliberate decision not to provide an overloaded min/max mbuf size variant
       
   185 @param aDes
       
   186 @param aHdrLen A header length
       
   187 */
       
   188 	{
       
   189 	TInt err = Alloc(aDes.Length() + aHdrLen);
       
   190 	if(err == KErrNone)
       
   191 		{
       
   192 		CopyIn(aDes, aHdrLen);	// NB! old version prepended explicit buf. wonder if that matters?
       
   193 		}
       
   194 	return err;
       
   195 	}
       
   196 
       
   197 
       
   198 EXPORT_C void RMBufChain::CreateL(const TDesC8& aDes, TInt aHdrLen)
       
   199 /**
       
   200 Create an Mbuf chain from a descriptor optionally allowing room at front for a protocol header.
       
   201 @param aDes
       
   202 @param aHdrLen A header length
       
   203 */
       
   204 	{
       
   205 	User::LeaveIfError(Create(aDes, aHdrLen));
       
   206 	}
       
   207 
       
   208 
       
   209 
       
   210 EXPORT_C void RMBufChain::FillZ(TInt aLen)
       
   211 /**
       
   212 Zero fill the first aLen bytes of an mbuf chain
       
   213 @param aLen the length (how many byte to be appended to the end)
       
   214 */
       
   215 	{
       
   216 	__ASSERT_ALWAYS(iNext!=NULL, CommsBuf::Panic(EMBuf_EmptyChain));
       
   217 
       
   218 	TInt n;
       
   219 	RMBuf* m = static_cast<RMBuf*>(iNext);
       
   220 
       
   221 	while(aLen>0 && m!=NULL)
       
   222 		{
       
   223 			n = aLen < m->Length() ? aLen : m->Length();
       
   224 			Mem::FillZ(m->Ptr(), n);
       
   225 			aLen -= n;
       
   226 			m = m->Next();
       
   227 		}
       
   228 	}
       
   229 
       
   230 
       
   231 EXPORT_C void RMBufChain::CopyL(RMBufChain& newChain, TInt anOffset, TInt aLen) const
       
   232 /**
       
   233 Copy data into a new chain starting at a given offset
       
   234 into this chain.
       
   235 Allocate sufficient mbufs to hold specfied amount of data,
       
   236 optionally zeroing the buffers.
       
   237 @param aLen A length of the cell
       
   238 */
       
   239 	{
       
   240 	User::LeaveIfError(Copy(newChain, anOffset, aLen, 0));
       
   241 	}
       
   242 
       
   243 EXPORT_C TInt RMBufChain::Copy(RMBufChain &newChain, TInt aOffset, TInt aLen, TInt aHdrReserve) const
       
   244 /**
       
   245 Copy data into a new chain starting at a given offset
       
   246 into this chain.
       
   247 - refer RMBufChain::AllocL notes regarding the deliberate decision not to provide an overloaded min/max mbuf size variant
       
   248 @param newChain A new chain, where the data is copied to
       
   249 @param aOffset A offset,
       
   250 @param aLen the length of the data to be copied
       
   251 @param aHdrReserve Amount of space (bytes) to offset the start of data from the start of the first buffer, so allowing
       
   252 subsequent prepending without further allocation (typically used for protocol headers)
       
   253 */
       
   254 	{
       
   255  	__ASSERT_ALWAYS(iNext!=NULL, CommsBuf::Panic(EMBuf_EmptyChain));
       
   256  	__ASSERT_ALWAYS(aLen>=0, CommsBuf::Panic(EMBuf_NegativeLength));
       
   257  	__ASSERT_ALWAYS(aOffset>=0, CommsBuf::Panic(EMBuf_NegativeOffset));
       
   258 
       
   259 	TInt n, n1, n2;
       
   260 	TUint8* p1, *p2;
       
   261 	RMBuf* m1, *m2;
       
   262 
       
   263 	TInt len = Length();
       
   264 	if (aOffset>0)
       
   265 		{
       
   266  		__ASSERT_ALWAYS(aOffset<len, CommsBuf::Panic(EMBuf_BadOffset));
       
   267 		n = len - aOffset;
       
   268 		len = Min(aLen, n);
       
   269 		}
       
   270 	else
       
   271 		{
       
   272 		len = Min(aLen, len);	
       
   273 		}		
       
   274 
       
   275 	TInt err = newChain.Alloc(len + aHdrReserve, *this);
       
   276 	if(err != KErrNone)
       
   277 		{
       
   278 		return err;
       
   279 		}
       
   280 
       
   281 	if (aOffset>0)
       
   282 		{
       
   283 		if ((m1 = static_cast<RMBuf*>(RCommsBufChain::Goto(aOffset, n, n1))) == NULL)
       
   284 			{
       
   285 			return KErrNone;				
       
   286 			}
       
   287 		p1 = m1->Buffer()+n;
       
   288 		}
       
   289 	else
       
   290 		{
       
   291 		m1 = static_cast<RMBuf*>(iNext);
       
   292 		p1 = m1->Ptr();
       
   293 		n1 = m1->Length();
       
   294 		}
       
   295 
       
   296     if (aHdrReserve > 0)
       
   297         {
       
   298         m2 = static_cast<RMBuf*>(newChain.First());
       
   299         if(aHdrReserve >= m2->Length())
       
   300             {
       
   301             // In principle we could have one or more buffers as header reserve, however it's not
       
   302             // obvious whether a chain can contain wholly empty buffers in it, ie whether code
       
   303             // walking the chain will have encountered such a situation. So we prevent this - in
       
   304             // practice this shouldn't pose a problem as the expected use is reserving capacity
       
   305             // within the copied buffer for subsequent pre-pending to avoid allocating another buf 
       
   306             newChain.Free();
       
   307             return KErrOverflow;
       
   308             }
       
   309         m2->SetData(aHdrReserve, m2->Length() - aHdrReserve);
       
   310         p2 = m2->Ptr();
       
   311         n2 = m2->Length();
       
   312         }
       
   313     else
       
   314         {
       
   315         m2 = static_cast<RMBuf*>(newChain.iNext);
       
   316         p2 = m2->Ptr();
       
   317         n2 = m2->Length();
       
   318         }
       
   319     
       
   320 	while (len>0)
       
   321 		{
       
   322  		__ASSERT_DEBUG(n1>0 && n2>0, CommsBuf::Panic(EMBuf_NegativeLength));
       
   323 
       
   324 		n = n1 < n2 ? n1 : n2;
       
   325 
       
   326 		Mem::Copy(p2, p1, n);
       
   327 
       
   328 		if (n1 -= n, n1 == 0)
       
   329 			{
       
   330 			if (m1 = m1->Next(), m1==NULL)
       
   331 				{
       
   332 				break;					
       
   333 				}
       
   334 
       
   335 			p1 = m1->Ptr();
       
   336 			n1 = m1->Length();
       
   337 			}
       
   338 		else
       
   339 			{
       
   340 			p1 += n;	
       
   341 			}
       
   342 			
       
   343 
       
   344 		if (n2 -= n, n2 == 0)
       
   345 			{
       
   346 			if (m2 = m2->Next(), m2==NULL)
       
   347 				{
       
   348 				break;					
       
   349 				}
       
   350 
       
   351 			p2 = m2->Ptr();
       
   352 			n2 = m2->Length();
       
   353 			}
       
   354 		else
       
   355 			{
       
   356 			p2 += n;	
       
   357 			}
       
   358 		len -= n;
       
   359 		}
       
   360 	return KErrNone;
       
   361 	}
       
   362 
       
   363 EXPORT_C void RMBufChain::CopyIn(const TDesC8& aDes, TInt aOffset/*=0*/)
       
   364 	{
       
   365 	RCommsBufChain::Write(aDes, aOffset);	
       
   366 	}
       
   367 
       
   368 EXPORT_C void RMBufChain::CopyOut(TDes8& aDes, TInt aOffset) const
       
   369 /**
       
   370 Copy data from an mbuf chain into linear buffer
       
   371 starting at specified offset.
       
   372 @param aDes the buffer to copy in to
       
   373 @param aOffset the offset
       
   374 */
       
   375 	{
       
   376 	RCommsBufChain::Read(aDes, aOffset);
       
   377 	}
       
   378 
       
   379 
       
   380 EXPORT_C void RMBufChain::Assign(RMBufQ& aQueue)
       
   381 /**
       
   382 Take ownership of Mbuf from a queue
       
   383 Previously allocated data (e.g. by a call to RMBufChain::AllocL) in the chain must be
       
   384 emptied (e.g. by calling RMBufChain::Free) before the assignment
       
   385 @param aQueue the queue
       
   386 @see RMBufChain::IsEmpty()
       
   387 @see RMBufChain::Free()
       
   388 */
       
   389 	{
       
   390 	__ASSERT_ALWAYS(iNext==NULL, CommsBuf::Panic(EMBuf_NotEmptyChain));
       
   391 	iNext = aQueue.First();
       
   392 	aQueue.Init();
       
   393 	}
       
   394 
       
   395 EXPORT_C void RMBufChain::Assign(RMBufChain& aChain)
       
   396 	{
       
   397 	RCommsBufChain::Assign(aChain);	
       
   398 	}
       
   399 
       
   400 EXPORT_C void RMBufChain::Append(RMBufChain& aChain)
       
   401 	{
       
   402 	RCommsBufChain::Append(aChain);	
       
   403 	}
       
   404 
       
   405 EXPORT_C void RMBufChain::AppendL(TInt aLen)
       
   406 /**
       
   407 Append space to the end of a MBuf chain
       
   408 @param aLen the length (how many byte to be appended to the end)
       
   409 */
       
   410 	{
       
   411 	User::LeaveIfError(Append(aLen));
       
   412 	}
       
   413 
       
   414 EXPORT_C TInt RMBufChain::Append(TInt aLen)
       
   415 /** 	  	 
       
   416 Append space to the end of a MBuf chain 	  	 
       
   417 - refer RMBufChain::AllocL notes regarding the deliberate decision not to provide an overloaded min/max mbuf size variant 	  	 
       
   418 @param aLen the length (how many byte to be appended to the end) 	  	 
       
   419 */
       
   420 	{
       
   421 	if(iNext == NULL)
       
   422 		{		
       
   423 		RMBufAllocator allocator;
       
   424 		return Append(aLen, allocator);		
       
   425 		}
       
   426 	return RCommsBufChain::Append(aLen);		
       
   427 	}
       
   428 
       
   429 // overloading for TLS
       
   430 EXPORT_C TInt RMBufChain::Append(TInt aLen, RMBufAllocator& aRMBufAllocator)
       
   431 	{
       
   432 	RMBuf* buf = static_cast<RMBuf*>(aRMBufAllocator.iPond.Alloc(aLen, 0, KMaxTInt));
       
   433 	if(buf == NULL)
       
   434 		{
       
   435 		return KErrNoMBufs;			
       
   436 		}
       
   437 
       
   438 	RCommsBufChain::Append(buf);
       
   439 	return KErrNone;
       
   440 	}
       
   441 
       
   442 
       
   443 EXPORT_C RMBuf* RMBufChain::Remove()
       
   444 /**
       
   445 Removes and returns the first RCommsBuf. The ownership of the returned RCommsBuf is with the caller
       
   446 */
       
   447 	{
       
   448 	RMBuf* buf = static_cast<RMBuf*>(iNext);
       
   449 	if(buf)
       
   450 		{
       
   451 		iNext = buf->Next();
       
   452 		buf->Unlink();
       
   453 		}
       
   454 
       
   455 	return buf;
       
   456 	}
       
   457 
       
   458 
       
   459 
       
   460 EXPORT_C void RMBufChain::PrependL(TInt aLen)
       
   461 /**
       
   462 Prepend space onto the front of a chain
       
   463 @param aLen the length of the space
       
   464 */
       
   465 	{
       
   466 	User::LeaveIfError(Prepend(aLen));
       
   467 	}
       
   468 
       
   469 EXPORT_C TInt RMBufChain::Prepend(TInt aLen)
       
   470 /** 	  	 
       
   471 Prepend space onto the front of a chain 	  	 
       
   472 - refer RMBufChain::AllocL notes regarding the deliberate decision not to provide an overloaded min/max mbuf size variant 	  	 
       
   473 @param aLen the length of the space 	  	 
       
   474 */
       
   475 	{
       
   476 	if(iNext)
       
   477 		{
       
   478 		return RCommsBufChain::Prepend(aLen);					
       
   479 		}
       
   480 	RMBufAllocator allocator;
       
   481 	return Prepend(aLen, allocator);	
       
   482 	}
       
   483 	
       
   484 // overloading for TLS
       
   485 EXPORT_C TInt RMBufChain::Prepend(TInt aLen, RMBufAllocator& aRMBufAllocator)
       
   486 	{
       
   487 	RMBuf* buf = static_cast<RMBuf*>(aRMBufAllocator.iPond.Alloc(aLen, 0, KMaxTInt));
       
   488 	if(buf == NULL)
       
   489 		{
       
   490 		return KErrNoMBufs;			
       
   491 		}
       
   492 
       
   493 	RMBufChain chain(buf);
       
   494 	RCommsBufChain::Prepend(chain);
       
   495 	return KErrNone;
       
   496 	}
       
   497 
       
   498 EXPORT_C void RMBufChain::Prepend(RMBuf* aBuf)
       
   499 	{
       
   500 	RCommsBufChain::Prepend(aBuf);	
       
   501 	}
       
   502 
       
   503 EXPORT_C void RMBufChain::Prepend(RMBufChain& aChain)
       
   504 	{
       
   505 	RCommsBufChain::Prepend(aChain);	
       
   506 	}
       
   507 
       
   508 
       
   509 EXPORT_C TInt RMBufChain::NumBufs() const
       
   510 /**
       
   511 Count the number of buffers in a chain
       
   512 */
       
   513 	{
       
   514 	__ASSERT_ALWAYS(iNext!=NULL, CommsBuf::Panic(EMBuf_EmptyChain));
       
   515 
       
   516 	TInt len = 0;
       
   517 	RMBuf* m = static_cast<RMBuf*>(iNext);
       
   518 	for (; m!=NULL; m = m->Next())
       
   519 		{
       
   520 		len++;			
       
   521 		}
       
   522 	return len;
       
   523 	}
       
   524 
       
   525 
       
   526 EXPORT_C void RMBufChain::SplitL(TInt anOffset, RMBufChain& newChain)
       
   527 /**
       
   528 Split a chain into two new chains
       
   529 Original chain gets the 1st half
       
   530 newChain gets the other half.
       
   531 @param anOffset The offset
       
   532 @param newChain The result chain
       
   533 */
       
   534 	{
       
   535 	User::LeaveIfError(RCommsBufChain::Split(anOffset, newChain));
       
   536 	}
       
   537 
       
   538 EXPORT_C TInt RMBufChain::Split(TInt anOffset, RMBufChain& newChain)
       
   539 /** 	  	 
       
   540 Split a chain into two new chains Original chain gets the 1st half 	  	 
       
   541 newChain gets the other half. 	  	 
       
   542 - refer RMBufChain::AllocL notes regarding the deliberate decision not to provide an overloaded min/max mbuf size variant 	  	 
       
   543 @param anOffset The offset 	  	 
       
   544 @param newChain The result chain 	  	 
       
   545 */
       
   546 	{
       
   547 	return RCommsBufChain::Split(anOffset, newChain);		
       
   548 	}
       
   549 
       
   550 // overloading for TLS
       
   551 EXPORT_C TInt RMBufChain::Split(TInt anOffset, RMBufChain& newChain, RMBufAllocator& /* aRMBufAllocator */)
       
   552 	{
       
   553 	return RCommsBufChain::Split ( anOffset, newChain );
       
   554 	}
       
   555 
       
   556 
       
   557 EXPORT_C void RMBufChain::Free()
       
   558 /** 	  	 
       
   559 Free an MBuf chain, returning it to the free Pool 	  	 
       
   560 A pointer to the first mbuf of the next packet is returned. 	  	 
       
   561 */
       
   562 	{
       
   563 	RCommsBufChain::Free ();	
       
   564 	}
       
   565 
       
   566 EXPORT_C void RMBufChain::TrimStart(TInt nBytes)
       
   567 /** 	  	 
       
   568 Trim chain upto offset 	  	 
       
   569 @param anOffset The offset 	  	 
       
   570 */
       
   571 	{
       
   572 	RCommsBufChain::TrimStart(nBytes);	
       
   573 	}
       
   574 
       
   575 EXPORT_C void RMBufChain::TrimEnd(TInt anOffset)
       
   576 /** 	  	 
       
   577 Trim chain after offset 	  	 
       
   578 @param anOffset The offset 	  	 
       
   579 */
       
   580 	{
       
   581 	RCommsBufChain::TrimEnd(anOffset);	
       
   582 	}
       
   583 
       
   584 EXPORT_C TBool RMBufChain::Goto(TInt anOffset, RMBuf* &resBuf, TInt& resOffset, TInt& resLength, RMBuf* &resPrevBuf) const
       
   585 /** 	  	 
       
   586 Goto specified byte offset into an Mbuf chain. Used as part of copyin/out, split etc to position 	  	 
       
   587 MBuf pointer and offset from start of iBuffer. 	  	 
       
   588 @param anOffset The offset 	  	 
       
   589 @param resBuf result buffer 	  	 
       
   590 @param resOffset result offset 	  	 
       
   591 @param resLength result length 	  	 
       
   592 @param resPrevBuf result previous Buf in the chain 	  	 
       
   593 @return ETrue if successful 	  	 
       
   594 */
       
   595 	{
       
   596 	RCommsBuf* commsResBuf;
       
   597 	RCommsBuf* commsResPrevBuf;
       
   598 	
       
   599 	commsResBuf = RCommsBufChain::Goto(anOffset, resOffset, resLength, commsResPrevBuf); 	
       
   600 	if(commsResBuf)
       
   601 		{
       
   602 		resBuf = static_cast<RMBuf*>(commsResBuf);
       
   603 		resPrevBuf = static_cast<RMBuf*>(commsResPrevBuf);
       
   604 		return ETrue;
       
   605 		}
       
   606 	return EFalse;	
       
   607 	}
       
   608 
       
   609 EXPORT_C TInt RMBufChain::Length() const
       
   610 /** 	  	 
       
   611 Return the number of bytes of actual data contained in an MBuf chain 	  	 
       
   612 */
       
   613 	{
       
   614 	return RCommsBufChain::Length ();	
       
   615 	}
       
   616 
       
   617 EXPORT_C RMBuf* RMBufChain::Last() const
       
   618 /**
       
   619 Find the last MBuf in a chain
       
   620 @return the last MBuf in the chain
       
   621 */
       
   622 	{
       
   623 	return static_cast<RMBuf*>(RCommsBufChain::Last());
       
   624 	}
       
   625 
       
   626 
       
   627 EXPORT_C TInt RMBufChain::Align(TInt aSize)
       
   628 /**
       
   629 Ensure that the first aSize bytes can be safely cast
       
   630 to a structure of size aSize.
       
   631 @param aSize A size
       
   632 @return the number of bytes actually aligned. This will be the min of aSize and chain length.
       
   633 */
       
   634 	{
       
   635 	return RCommsBufChain::Align ( aSize );
       
   636 	}