persistentstorage/store/USTRM/US_BUF.CPP
changeset 0 08ec8eefde2f
child 51 7d4490026038
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 1998-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 //
       
    15 
       
    16 #include "US_STD.H"
       
    17 
       
    18 EXPORT_C TInt MStreamBuf::Synch()
       
    19 
       
    20 
       
    21 /** Synchronises the stream buffer with the stream, returning any error.
       
    22 
       
    23 In effect, this ensures that buffered data is delivered to the stream.
       
    24 
       
    25 This function calls SynchL() inside a TRAPD harness and returns the leave 
       
    26 code if a leave occurs.
       
    27 
       
    28 @return KErrNone, if successful; otherwise one of the other system wide error 
       
    29 codes.
       
    30 @see MStreamBuf::SynchL()
       
    31 @see MStreamBuf::DoSynchL() */
       
    32 	{
       
    33 	TRAPD(r,SynchL());
       
    34 	return r;
       
    35 	}
       
    36 
       
    37 EXPORT_C void MStreamBuf::Close()
       
    38 /** Closes the stream buffer.
       
    39 
       
    40 This function attempts to synchronise buffered data with the stream before 
       
    41 freeing any resources. All errors are ignored.
       
    42 
       
    43 @see MStreamBuf::Synch()
       
    44 @see MStreamBuf::Release() */
       
    45 	{
       
    46 	Synch();
       
    47 	Release();
       
    48 	}
       
    49 
       
    50 EXPORT_C void MStreamBuf::PushL()
       
    51 /** Puts a cleanup item for this object onto the cleanup stack.
       
    52 
       
    53 This allows allocated resources to be cleaned up if a subsequent leave occurs. */
       
    54 	{
       
    55 	CleanupReleasePushL(*this);
       
    56 	}
       
    57 
       
    58 EXPORT_C TInt MStreamBuf::Read(TDes8& aDes,TRequestStatus& aStatus)
       
    59 /** Reads data, asynchronously, from the stream buffer into the specified descriptor; 
       
    60 request completion is guaranteed, even if request initiation fails.
       
    61 
       
    62 The function calls the virtual function DoReadL(TDes8&,TInt,TRequestStatus&) 
       
    63 to implement this behaviour. The maximum number of bytes to be read is the 
       
    64 value of the maximum length of the descriptor.
       
    65 
       
    66 @param aDes The target descriptor for the data read from the stream buffer.
       
    67 @param aStatus The request status that indicates the completion status of this 
       
    68 asynchronous request.
       
    69 @return The maximum number of bytes to be read, as used in this request. This 
       
    70 value can be different to the maximum length of the descriptor; this is dependent 
       
    71 on the implementation.
       
    72 @see MStreamBuf::DoReadL() */
       
    73 	{
       
    74 	return Read(aDes,aDes.MaxLength(),aStatus);
       
    75 	}
       
    76 
       
    77 EXPORT_C TInt MStreamBuf::Read(TDes8& aDes,TInt aMaxLength,TRequestStatus& aStatus)
       
    78 /** Reads data, asynchronously, from the stream buffer into the specified descriptor; 
       
    79 request completion is guaranteed, even if request initiation fails.
       
    80 
       
    81 The function calls the virtual function DoReadL(TDes8&,TInt,TRequestStatus&) 
       
    82 to implement this behaviour.
       
    83 
       
    84 @param aDes The target descriptor for the data read from the stream buffer.
       
    85 @param aMaxLength The maximum number of bytes to be read.
       
    86 @param aStatus The request status that indicates the completion status of this 
       
    87 asynchronous request.
       
    88 @return The maximum number of bytes to be read, as used in this request. This 
       
    89 can be different to the value supplied in aMaxLength; this is dependent on 
       
    90 the implementation.
       
    91 @see MStreamBuf::DoReadL() */
       
    92 	{
       
    93 	TInt len=0;
       
    94 	TRAPD(r,len=DoReadL(aDes,aMaxLength,aStatus));
       
    95 	if (r!=KErrNone)
       
    96 		{
       
    97 		TRequestStatus* stat=&aStatus;
       
    98 		User::RequestComplete(stat,r);
       
    99 		}
       
   100 	return len;
       
   101 	}
       
   102 
       
   103 EXPORT_C TInt MStreamBuf::ReadL(TDes8& aDes,TRequestStatus& aStatus)
       
   104 /** Reads data, asynchronously, from the stream buffer into the specified descriptor.
       
   105 
       
   106 The function calls the virtual function DoReadL(TDes8&,TInt,TRequestStatus&) 
       
   107 to implement this behaviour. The maximum number of bytes to be read is the 
       
   108 maximum length of the descriptor.
       
   109 
       
   110 If the function leaves, then no read request will have been initiated.
       
   111 
       
   112 @param aDes The target descriptor for the data read from the stream buffer.
       
   113 @param aStatus The request status that indicates the completion status of this 
       
   114 asynchronous request.
       
   115 @return The maximum number of bytes to be read, as used in this request. This 
       
   116 value can be different to the maximum length of the descriptor; this is dependent 
       
   117 on the implementation.
       
   118 @see MStreamBuf::DoReadL() */
       
   119 	{
       
   120 	return DoReadL(aDes,aDes.MaxLength(),aStatus);
       
   121 	}
       
   122 
       
   123 EXPORT_C TInt MStreamBuf::ReadL(MStreamInput& anInput,TInt aMaxLength)
       
   124 /** Reads data from the stream buffer into the specified data sink.
       
   125 
       
   126 The function uses the virtual function DoReadL(MStreamInput&,TStreamTransfer) 
       
   127 to implement this behaviour.
       
   128 
       
   129 @param anInput The data sink which is the target for the read operation.
       
   130 @param aMaxLength The maximum amount of data available to be read.
       
   131 @return The amount of data that was not consumed. */
       
   132 	{
       
   133 	return aMaxLength-DoReadL(anInput,TStreamTransfer(aMaxLength)).Left();
       
   134 	}
       
   135 
       
   136 EXPORT_C TInt MStreamBuf::Write(const TDesC8& aDes,TRequestStatus& aStatus)
       
   137 /** Writes data, asynchronously, from the specified descriptor into the stream buffer; 
       
   138 request completion is guaranteed, even if request initiation fails.
       
   139 
       
   140 The function calls the virtual function DoWriteL(const TDesC8&,TInt,TRequestStatus&) 
       
   141 to implement this behaviour. The maximum number of bytes to be written is 
       
   142 the value of the maximum length of the descriptor.
       
   143 
       
   144 @param aDes The source descriptor for the data to be written into the stream 
       
   145 buffer.
       
   146 @param aStatus The request status that indicates the completion status of this 
       
   147 asynchronous request.
       
   148 @return The maximum number of bytes to be written, as used in this request. 
       
   149 This can be different to the value supplied in aMaxLength; this is dependent 
       
   150 on the implementation.
       
   151 @see MStreamBuf::DoWriteL() */
       
   152 	{
       
   153 	return Write(aDes,aDes.Length(),aStatus);
       
   154 	}
       
   155 
       
   156 EXPORT_C TInt MStreamBuf::Write(const TDesC8& aDes,TInt aMaxLength,TRequestStatus& aStatus)
       
   157 //
       
   158 // Write up to aMaxLength bytes with guaranteed completion.
       
   159 //
       
   160 	{
       
   161 	TInt len=0;
       
   162 	TRAPD(r,len=DoWriteL(aDes,aMaxLength,aStatus));
       
   163 	if (r!=KErrNone)
       
   164 		{
       
   165 		TRequestStatus* stat=&aStatus;
       
   166 		User::RequestComplete(stat,r);
       
   167 		}
       
   168 	return len;
       
   169 	}
       
   170 
       
   171 EXPORT_C TInt MStreamBuf::WriteL(const TDesC8& aDes,TRequestStatus& aStatus)
       
   172 /** Writes data, asynchronously, from the specified descriptor into the stream buffer.
       
   173 
       
   174 The function calls the virtual function DoWriteL(const TDesC8&,TInt,TRequestStatus&) 
       
   175 to implement this behaviour. The maximum number of bytes to be written is 
       
   176 the value of the maximum length of the descriptor.
       
   177 
       
   178 If the function leaves, then no write request will have been initiated.
       
   179 
       
   180 @param aDes The source descriptor for the data to be written into the stream 
       
   181 buffer.
       
   182 @param aStatus The request status that indicates the completion status of this 
       
   183 asynchronous request.
       
   184 @return The maximum number of bytes to be written, as used in this request. 
       
   185 This can be different to the maximum length of the descriptor; this is dependent 
       
   186 on the implementation.
       
   187 @see MStreamBuf::DoWriteL() */
       
   188 	{
       
   189 	return DoWriteL(aDes,aDes.Length(),aStatus);
       
   190 	}
       
   191 
       
   192 EXPORT_C TInt MStreamBuf::WriteL(MStreamOutput& anOutput,TInt aMaxLength)
       
   193 /** Writes data into the stream buffer from the specified data source.
       
   194 
       
   195 The function calls the virtual function DoWriteL(MStreamOutput&,TStreamTransfer) 
       
   196 to implement this behaviour.
       
   197 
       
   198 @param anOutput The data source for the write operation.
       
   199 @param aMaxLength The maximum amount of data available to be written.
       
   200 @return The amount of data that was not consumed. */
       
   201 	{
       
   202 	return aMaxLength-DoWriteL(anOutput,TStreamTransfer(aMaxLength)).Left();
       
   203 	}
       
   204 
       
   205 EXPORT_C void MStreamBuf::DoRelease()
       
   206 /** Frees resources before abandoning the stream buffer.
       
   207 
       
   208 It is called by Release().
       
   209 
       
   210 This implementation is empty, but classes derived from MStreamBuf can provide 
       
   211 their own implementation, if necessary.
       
   212 
       
   213 @see MStreamBuf::Release() */
       
   214 	{}
       
   215 
       
   216 EXPORT_C void MStreamBuf::DoSynchL()
       
   217 /** Synchronises the stream buffer with the stream, leaving if any error occurs.
       
   218 
       
   219 In effect, this ensures that buffered data is delivered to the stream.
       
   220 
       
   221 It is called by SynchL().
       
   222 
       
   223 This implementation is empty, but classes derived from MStreamBuf can provide 
       
   224 their own implementation, if necessary.
       
   225 
       
   226 @see MStreamBuf::SynchL() */
       
   227 	{}
       
   228 
       
   229 EXPORT_C TInt MStreamBuf::DoReadL(TAny*,TInt)
       
   230 //
       
   231 // Cannot read from this stream buffer.
       
   232 //
       
   233 	{
       
   234 	Panic(EStreamCannotRead);
       
   235 	return TInt();
       
   236 	}
       
   237 
       
   238 EXPORT_C TInt MStreamBuf::DoReadL(TDes8& aDes,TInt aMaxLength,TRequestStatus& aStatus)
       
   239 /** Reads data from the stream buffer into the specified descriptor.
       
   240 
       
   241 This function is called by ReadL(TDes8&,TInt,TRequestStatus&).
       
   242 
       
   243 This implementation deals with the request synchronously, and completes the 
       
   244 request with KErrNone. Other implementations may choose to deal with this 
       
   245 in a true asynchronous manner.
       
   246 
       
   247 In addition, the read operation itself uses the DoReadL(TAny*,TInt) variant.
       
   248 
       
   249 @param aDes The target descriptor for the data read from the stream buffer. 
       
   250 On return, the length of the descriptor is set to the number of bytes read 
       
   251 from the stream buffer.
       
   252 @param aMaxLength The maximum number of bytes to be read. This value must not 
       
   253 be greater than the maximum length of the descriptor, otherwise the function 
       
   254 raises a STORE-Stream 2 panic.
       
   255 @param aStatus The request status that indicates the completion status of this 
       
   256 asynchronous request.
       
   257 @return The maximum number of bytes to be read, as used in this request. This 
       
   258 implementation uses, and returns, the value supplied in aMaxLength. Other 
       
   259 implementations may choose to use a different value.
       
   260 @see MStreamBuf::ReadL() */
       
   261 	{
       
   262 	__ASSERT_DEBUG(aMaxLength<=aDes.MaxLength(),Panic(EStreamReadBeyondEnd));
       
   263 	aDes.SetLength(DoReadL((TUint8*)aDes.Ptr(),aMaxLength));
       
   264 	TRequestStatus* stat=&aStatus;
       
   265 	User::RequestComplete(stat,KErrNone);
       
   266 	return aMaxLength;
       
   267 	}
       
   268 
       
   269 EXPORT_C TStreamTransfer MStreamBuf::DoReadL(MStreamInput& anInput,TStreamTransfer aTransfer)
       
   270 /** Reads data from the stream into the specified data sink.
       
   271 
       
   272 It is called by ReadL(MStreamInput&,TStreamTransfer).
       
   273 
       
   274 This implementation calls the sink's ReadFromL() function, which performs 
       
   275 the read (transfer) operation.
       
   276 
       
   277 This implementation of DoReadL() is called for streams that do not have buffering 
       
   278 capabilities, and that are derived directly from this class.
       
   279 
       
   280 @param anInput The target data sink.
       
   281 @param aTransfer A stream transfer object defining the amount of data available 
       
   282 to be read.
       
   283 @return A stream transfer object defining the amount of data that was not consumed.
       
   284 @see MStreamInput::ReadFromL() */
       
   285 	{
       
   286 	return anInput.ReadFromL(*this,aTransfer);
       
   287 	}
       
   288 
       
   289 EXPORT_C void MStreamBuf::DoWriteL(const TAny*,TInt)
       
   290 //
       
   291 // Cannot write to this stream buffer.
       
   292 //
       
   293 	{
       
   294 	Panic(EStreamCannotWrite);
       
   295 	}
       
   296 
       
   297 EXPORT_C TInt MStreamBuf::DoWriteL(const TDesC8& aDes,TInt aMaxLength,TRequestStatus& aStatus)
       
   298 /** Writes data from the specified descriptor into this stream buffer.
       
   299 
       
   300 This function is called by WriteL(const TDesC8&,TInt,TRequestStatus&).
       
   301 
       
   302 This implementation deals with the request synchronously, and completes the 
       
   303 request with KErrNone. Other implementations may choose to deal with this 
       
   304 in a true asynchronous manner.
       
   305 
       
   306 In addition, the write operation itself uses the DoWriteL(TAny*,TInt) variant.
       
   307 
       
   308 @param aDes The source descriptor for the data to be written into the stream 
       
   309 buffer.
       
   310 @param aMaxLength The number of bytes to be written. This value must not be 
       
   311 greater than the maximum length of the descriptor, otherwise the function 
       
   312 raises a STORE-Stream 6 panic.
       
   313 @param aStatus The request status that indicates the completion status of this 
       
   314 asynchronous request.
       
   315 @return The maximum number of bytes to be written, as used in this request. 
       
   316 This implementation uses, and returns, the value supplied in aMaxLength. Other 
       
   317 implementations may choose to use a different value.
       
   318 @see MStreamBuf::WriteL() */
       
   319 	{
       
   320 	__ASSERT_DEBUG(aMaxLength<=aDes.Length(),Panic(EStreamWriteBeyondEnd));
       
   321 	DoWriteL(aDes.Ptr(),aMaxLength);
       
   322 	TRequestStatus* stat=&aStatus;
       
   323 	User::RequestComplete(stat,KErrNone);
       
   324 	return aMaxLength;
       
   325 	}
       
   326 
       
   327 EXPORT_C TStreamTransfer MStreamBuf::DoWriteL(MStreamOutput& anOutput,TStreamTransfer aTransfer)
       
   328 //
       
   329 // Default implementation turning around to anOutput.
       
   330 //
       
   331 	{
       
   332 	return anOutput.WriteToL(*this,aTransfer);
       
   333 	}
       
   334 
       
   335 EXPORT_C TStreamPos MStreamBuf::DoSeekL(TMark,TStreamLocation,TInt)
       
   336 //
       
   337 // This stream buffer does not support seeking.
       
   338 //
       
   339 	{
       
   340 	Panic(EStreamCannotSeek);
       
   341 	TStreamPos streamPos(-1);
       
   342 	return streamPos;
       
   343 	}
       
   344 
       
   345 EXPORT_C TStreamBuf::TStreamBuf()
       
   346 	: iRPtr(NULL),iREnd(NULL),iWPtr(NULL),iWEnd(NULL)
       
   347 /** Sets the pointers that mark out the read and write areas within the intermediate 
       
   348 buffer to null. */
       
   349 	{}
       
   350 
       
   351 EXPORT_C void TStreamBuf::SetBuf(TArea anArea,TUint8* aPtr,TUint8* anEnd)
       
   352 /** Sets the start and end points of the read and/or the write area within the intermediate 
       
   353 buffer.
       
   354 
       
   355 A start point is always within an area; an end point is always the first byte 
       
   356 beyond the end of an area.
       
   357 
       
   358 @param anArea The areas within the intermediate buffer for which the start 
       
   359 and end points are to be set. These can be the read area and/or the write 
       
   360 area, as indicated by the ERead and EWrite bits. Only these bits can be set, 
       
   361 otherwise the function raises a STORE-Stream 17 panic.
       
   362 @param aPtr The start point.
       
   363 @param anEnd The end point.
       
   364 @see MStreamBuf::TRead
       
   365 @see MStreamBuf::TWrite */
       
   366 	{
       
   367 	__ASSERT_ALWAYS(!(anArea&~(ERead|EWrite)),Panic(EStreamAreaInvalid));
       
   368 	if (anArea&ERead)
       
   369 		SetBuf(ERead,aPtr,anEnd);
       
   370 	if (anArea&EWrite)
       
   371 		SetBuf(EWrite,aPtr,anEnd);
       
   372 	}
       
   373 
       
   374 EXPORT_C void TStreamBuf::SetPtr(TArea anArea,TUint8* aPtr)
       
   375 /** Sets the start point of the read and/or the write area within the intermediate 
       
   376 buffer.
       
   377 
       
   378 A start point is always within an area.
       
   379 
       
   380 @param anArea The areas within the intermediate buffer for which the start 
       
   381 point is to be set. These can be the read area and/or the write area, as indicated 
       
   382 by the ERead and EWrite bits. Only these bits can be set, otherwise the function 
       
   383 raises a STORE-Stream 17 panic.
       
   384 @param aPtr The start point.
       
   385 @see MStreamBuf::TRead
       
   386 @see MStreamBuf::TWrite */
       
   387 	{
       
   388 	__ASSERT_ALWAYS(!(anArea&~(ERead|EWrite)),Panic(EStreamAreaInvalid));
       
   389 	if (anArea&ERead)
       
   390 		SetPtr(ERead,aPtr);
       
   391 	if (anArea&EWrite)
       
   392 		SetPtr(EWrite,aPtr);
       
   393 	}
       
   394 
       
   395 EXPORT_C void TStreamBuf::SetEnd(TArea anArea,TUint8* anEnd)
       
   396 //
       
   397 // Set the end pointer for the buffer area(s) indicated by anArea.
       
   398 //
       
   399 	{
       
   400 	__ASSERT_ALWAYS(!(anArea&~(ERead|EWrite)),Panic(EStreamAreaInvalid));
       
   401 	if (anArea&ERead)
       
   402 		SetEnd(ERead,anEnd);
       
   403 	if (anArea&EWrite)
       
   404 		SetEnd(EWrite,anEnd);
       
   405 	}
       
   406 
       
   407 EXPORT_C TUint8* TStreamBuf::Ptr(TArea anArea) const
       
   408 /** Gets the current start point of the read or write area within the intermediate 
       
   409 buffer.
       
   410 
       
   411 @param anArea The area within the intermediate buffer for which the start 
       
   412 point is to be fetched. This can be either the read area or the write area, 
       
   413 as indicated by the ERead and EWrite bits. Only one of these can be set, otherwise 
       
   414 the function raises a STORE-Stream 17 panic.
       
   415 @return The start point.
       
   416 @see MStreamBuf::TRead
       
   417 @see MStreamBuf::TWrite */
       
   418 	{
       
   419 	if (anArea==ERead)
       
   420 		return Ptr(ERead);
       
   421 //
       
   422 	__ASSERT_ALWAYS(anArea==EWrite,Panic(EStreamAreaInvalid));
       
   423 	return Ptr(EWrite);
       
   424 	}
       
   425 
       
   426 EXPORT_C TUint8* TStreamBuf::End(TArea anArea) const
       
   427 /** Gets the current end point of the read or write area within the intermediate 
       
   428 buffer.
       
   429 
       
   430 An end point is always the first byte beyond the end of an area.
       
   431 
       
   432 @param anArea The area within the intermediate buffer for which the end point 
       
   433 is to be fetched. This can be either the read area or the write area, as indicated 
       
   434 by the ERead and EWrite bits. Only one of these can be set, otherwise the 
       
   435 function raises a STORE-Stream 17 panic.
       
   436 @return The end point. */
       
   437 	{
       
   438 	if (anArea==ERead)
       
   439 		return End(ERead);
       
   440 //
       
   441 	__ASSERT_ALWAYS(anArea==EWrite,Panic(EStreamAreaInvalid));
       
   442 	return End(EWrite);
       
   443 	}
       
   444 
       
   445 EXPORT_C TInt TStreamBuf::Avail(TArea anArea) const
       
   446 /** Gets the number of bytes available in the read or write area within the intermediate 
       
   447 buffer.
       
   448 
       
   449 @param anArea The area within the intermediate buffer for which the number 
       
   450 of available bytes is to be fetched. This can be either the read area or the 
       
   451 write area, as indicated by the ERead and EWrite bits. Only one of these can 
       
   452 be set, otherwise the function raises a STORE-Stream 17 panic.
       
   453 @return The number of bytes available. */
       
   454 	{
       
   455 	if (anArea==ERead)
       
   456 		return Avail(ERead);
       
   457 //
       
   458 	__ASSERT_ALWAYS(anArea==EWrite,Panic(EStreamAreaInvalid));
       
   459 	return Avail(EWrite);
       
   460 	}
       
   461 
       
   462 EXPORT_C TInt TStreamBuf::DoReadL(TAny* aPtr,TInt aMaxLength)
       
   463 /** Reads data from the intermediate buffer into the specified memory location.
       
   464 
       
   465 The function calls the virtual function UnderfLowL() to give concrete implementations 
       
   466 the chance to refill the intermediate buffer, and satisfy the caller's requirements.
       
   467 
       
   468 This implementation overrides the one supplied by the base class MStreamBuf, 
       
   469 and is called by, MStreamBuf::ReadL(TAny*,TInt).
       
   470 
       
   471 @param aPtr A pointer to the target memory location for the data read from 
       
   472 the intermediate buffer.
       
   473 @param aMaxLength The maximum number of bytes to be read.
       
   474 @return The number of bytes read. This may be less than the amount requested.
       
   475 @see MStreamBuf::ReadL()
       
   476 @see MStreamBuf::DoReadL() */
       
   477 	{
       
   478 	__ASSERT_DEBUG(aMaxLength>=0,Panic(EStreamReadLengthNegative));
       
   479 	__ASSERT_DEBUG(aMaxLength>0,Panic(EStreamReadNoTransfer));
       
   480 	__ASSERT_DEBUG(Ptr(ERead)!=NULL||End(ERead)==NULL,Panic(EStreamCannotRead));
       
   481 	TInt left=aMaxLength;
       
   482 	TInt avail=Avail(ERead);
       
   483 	__ASSERT_DEBUG(avail>=0,User::Invariant());
       
   484 	if (avail==0)
       
   485 		goto underflow;
       
   486 //
       
   487 	do
       
   488 		{
       
   489 		__ASSERT_DEBUG(avail==Avail(ERead),Panic(EStreamUnderflowInBreach));
       
   490 		__ASSERT_DEBUG(left>0&&avail>0,User::Invariant());
       
   491 		{
       
   492 		TInt len=Min(left,avail);
       
   493 		TUint8* ptr=Ptr(ERead);
       
   494 		aPtr=Mem::Copy(aPtr,ptr,len);
       
   495 		SetPtr(ERead,ptr+len);
       
   496 		left-=len;
       
   497 		if (left==0)
       
   498 			return aMaxLength; // that's it
       
   499 		}
       
   500 //
       
   501 	underflow:
       
   502 		avail=UnderflowL(left);
       
   503 		} while (avail>0);
       
   504 	__ASSERT_DEBUG(avail==0&&Avail(ERead)==0,Panic(EStreamUnderflowInBreach));
       
   505 	return aMaxLength-left;
       
   506 	}
       
   507 
       
   508 EXPORT_C TStreamTransfer TStreamBuf::DoReadL(MStreamInput& anInput,TStreamTransfer aTransfer)
       
   509 /** Reads data from the intermediate buffer and, if necessary, any remaining data 
       
   510 from the stream to the specified target stream input object.
       
   511 
       
   512 It is called by ReadL(MStreamInput&,TStreamTransfer).
       
   513 
       
   514 The intermediate buffer is emptied first by calling the target stream input's 
       
   515 PushL() function, which performs the read from intermediate buffer operation. 
       
   516 Any remaining data is then read from the stream by calling the target stream 
       
   517 object's ReadFromL() function, which performs the read from stream operation.
       
   518 
       
   519 This implementation is called for streams that have buffering capabilities 
       
   520 and are derived from this class.
       
   521 
       
   522 @param anInput The target stream input object. 
       
   523 @param aTransfer A stream transfer object defining the amount of data available 
       
   524 to be written.
       
   525 @return The amount of data that was not consumed.
       
   526 @see MStreamInput::ReadFromL()
       
   527 @see MStreamInput::PushL() */
       
   528 	{
       
   529 	__ASSERT_DEBUG(aTransfer>0,Panic(EStreamReadNoTransfer));
       
   530 	__ASSERT_DEBUG(Ptr(ERead)!=NULL||End(ERead)==NULL,Panic(EStreamCannotRead));
       
   531 	__ASSERT_DEBUG(Avail(ERead)>=0,User::Invariant());
       
   532 	TInt len=aTransfer[Avail(ERead)];
       
   533 	if (len>0)
       
   534 		{
       
   535 		__DEBUG(TInt avail=Avail(ERead)); // may be pushing into this streambuf
       
   536 		TUint8* ptr=Ptr(ERead);
       
   537 		len=anInput.PushL(ptr,len);
       
   538 		__ASSERT_DEBUG(len>=0&&len<=aTransfer[avail]&&Ptr(ERead)==ptr&&Avail(ERead)>=avail,Panic(EStreamPushInBreach));
       
   539 		SetPtr(ERead,ptr+len);
       
   540 		aTransfer-=len;
       
   541 		}
       
   542 	if (aTransfer>0)
       
   543 		aTransfer=anInput.ReadFromL(*this,aTransfer);
       
   544 	return aTransfer;
       
   545 	}
       
   546 
       
   547 EXPORT_C void TStreamBuf::DoWriteL(const TAny* aPtr,TInt aLength)
       
   548 /** Writes data from the specified memory location into the intermediate buffer.
       
   549 
       
   550 The function calls the virtual function OverfLowL() to give concrete implementations 
       
   551 the chance to forward the intermediate buffer content to its destination.
       
   552 
       
   553 This implementation overrides the one supplied by the base class MStreamBuf, 
       
   554 and is called by MStreamBuf::WriteL(const TAny*,TInt).
       
   555 
       
   556 @param aPtr A pointer to the source memory location for the data to be written 
       
   557 to the intermediate buffer.
       
   558 @param aLength The number of bytes to be written.
       
   559 @return The number of bytes written.
       
   560 @see MStreamBuf::WriteL()
       
   561 @see MStreamBuf::DoWriteL() */
       
   562 	{
       
   563 	__ASSERT_DEBUG(aLength>=0,Panic(EStreamWriteLengthNegative));
       
   564 	__ASSERT_DEBUG(aLength>0,Panic(EStreamWriteNoTransfer));
       
   565 	__ASSERT_DEBUG(Ptr(EWrite)!=NULL||End(EWrite)==NULL,Panic(EStreamCannotWrite));
       
   566 	TInt avail=Avail(EWrite);
       
   567 	__ASSERT_DEBUG(avail>=0,User::Invariant());
       
   568 	if (avail==0)
       
   569 		goto overflow;
       
   570 //
       
   571 	for(;;)
       
   572 		{
       
   573 		__ASSERT_DEBUG(avail>0,Panic(EStreamOverflowInBreach));
       
   574 		__ASSERT_DEBUG(aLength>0,User::Invariant());
       
   575 		{
       
   576 		TInt len=Min(aLength,avail);
       
   577 		SetPtr(EWrite,Mem::Copy(Ptr(EWrite),aPtr,len));
       
   578 		aLength-=len;
       
   579 		if (aLength==0)
       
   580 			return; // done
       
   581 //
       
   582 		aPtr=(TUint8*)aPtr+len;
       
   583 		}
       
   584 //
       
   585 	overflow:
       
   586 		OverflowL();
       
   587 		avail=Avail(EWrite);
       
   588 		};
       
   589 	}
       
   590 
       
   591 EXPORT_C TStreamTransfer TStreamBuf::DoWriteL(MStreamOutput& anOutput,TStreamTransfer aTransfer)
       
   592 //
       
   593 // Default implementation filling the buffer before turning around to anOutput.
       
   594 //
       
   595 	{
       
   596 	__ASSERT_DEBUG(aTransfer>0,Panic(EStreamWriteNoTransfer));
       
   597 	__ASSERT_DEBUG(Ptr(EWrite)!=NULL||End(EWrite)==NULL,Panic(EStreamCannotWrite));
       
   598 	__ASSERT_DEBUG(Avail(EWrite)>=0,User::Invariant());
       
   599 	TInt len=aTransfer[Avail(EWrite)];
       
   600 	if (len>0)
       
   601 		{
       
   602 		__DEBUG(TInt avail=Avail(EWrite)); // may be pulling from this streambuf
       
   603 		TUint8* ptr=Ptr(EWrite);
       
   604 		len=anOutput.PullL(ptr,len);
       
   605 		__ASSERT_DEBUG(len>=0&&len<=aTransfer[avail]&&Ptr(EWrite)==ptr&&Avail(EWrite)>=avail,Panic(EStreamPullInBreach));
       
   606 		SetPtr(EWrite,ptr+len);
       
   607 		aTransfer-=len;
       
   608 		}
       
   609 	if (aTransfer>0)
       
   610 		aTransfer=anOutput.WriteToL(*this,aTransfer);
       
   611 	return aTransfer;
       
   612 	}
       
   613