persistentstorage/store/USTRM/US_BUF.CPP
changeset 0 08ec8eefde2f
child 51 7d4490026038
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/store/USTRM/US_BUF.CPP	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,613 @@
+// Copyright (c) 1998-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 "US_STD.H"
+
+EXPORT_C TInt MStreamBuf::Synch()
+
+
+/** Synchronises the stream buffer with the stream, returning any error.
+
+In effect, this ensures that buffered data is delivered to the stream.
+
+This function calls SynchL() inside a TRAPD harness and returns the leave 
+code if a leave occurs.
+
+@return KErrNone, if successful; otherwise one of the other system wide error 
+codes.
+@see MStreamBuf::SynchL()
+@see MStreamBuf::DoSynchL() */
+	{
+	TRAPD(r,SynchL());
+	return r;
+	}
+
+EXPORT_C void MStreamBuf::Close()
+/** Closes the stream buffer.
+
+This function attempts to synchronise buffered data with the stream before 
+freeing any resources. All errors are ignored.
+
+@see MStreamBuf::Synch()
+@see MStreamBuf::Release() */
+	{
+	Synch();
+	Release();
+	}
+
+EXPORT_C void MStreamBuf::PushL()
+/** Puts a cleanup item for this object onto the cleanup stack.
+
+This allows allocated resources to be cleaned up if a subsequent leave occurs. */
+	{
+	CleanupReleasePushL(*this);
+	}
+
+EXPORT_C TInt MStreamBuf::Read(TDes8& aDes,TRequestStatus& aStatus)
+/** Reads data, asynchronously, from the stream buffer into the specified descriptor; 
+request completion is guaranteed, even if request initiation fails.
+
+The function calls the virtual function DoReadL(TDes8&,TInt,TRequestStatus&) 
+to implement this behaviour. The maximum number of bytes to be read is the 
+value of the maximum length of the descriptor.
+
+@param aDes The target descriptor for the data read from the stream buffer.
+@param aStatus The request status that indicates the completion status of this 
+asynchronous request.
+@return The maximum number of bytes to be read, as used in this request. This 
+value can be different to the maximum length of the descriptor; this is dependent 
+on the implementation.
+@see MStreamBuf::DoReadL() */
+	{
+	return Read(aDes,aDes.MaxLength(),aStatus);
+	}
+
+EXPORT_C TInt MStreamBuf::Read(TDes8& aDes,TInt aMaxLength,TRequestStatus& aStatus)
+/** Reads data, asynchronously, from the stream buffer into the specified descriptor; 
+request completion is guaranteed, even if request initiation fails.
+
+The function calls the virtual function DoReadL(TDes8&,TInt,TRequestStatus&) 
+to implement this behaviour.
+
+@param aDes The target descriptor for the data read from the stream buffer.
+@param aMaxLength The maximum number of bytes to be read.
+@param aStatus The request status that indicates the completion status of this 
+asynchronous request.
+@return The maximum number of bytes to be read, as used in this request. This 
+can be different to the value supplied in aMaxLength; this is dependent on 
+the implementation.
+@see MStreamBuf::DoReadL() */
+	{
+	TInt len=0;
+	TRAPD(r,len=DoReadL(aDes,aMaxLength,aStatus));
+	if (r!=KErrNone)
+		{
+		TRequestStatus* stat=&aStatus;
+		User::RequestComplete(stat,r);
+		}
+	return len;
+	}
+
+EXPORT_C TInt MStreamBuf::ReadL(TDes8& aDes,TRequestStatus& aStatus)
+/** Reads data, asynchronously, from the stream buffer into the specified descriptor.
+
+The function calls the virtual function DoReadL(TDes8&,TInt,TRequestStatus&) 
+to implement this behaviour. The maximum number of bytes to be read is the 
+maximum length of the descriptor.
+
+If the function leaves, then no read request will have been initiated.
+
+@param aDes The target descriptor for the data read from the stream buffer.
+@param aStatus The request status that indicates the completion status of this 
+asynchronous request.
+@return The maximum number of bytes to be read, as used in this request. This 
+value can be different to the maximum length of the descriptor; this is dependent 
+on the implementation.
+@see MStreamBuf::DoReadL() */
+	{
+	return DoReadL(aDes,aDes.MaxLength(),aStatus);
+	}
+
+EXPORT_C TInt MStreamBuf::ReadL(MStreamInput& anInput,TInt aMaxLength)
+/** Reads data from the stream buffer into the specified data sink.
+
+The function uses the virtual function DoReadL(MStreamInput&,TStreamTransfer) 
+to implement this behaviour.
+
+@param anInput The data sink which is the target for the read operation.
+@param aMaxLength The maximum amount of data available to be read.
+@return The amount of data that was not consumed. */
+	{
+	return aMaxLength-DoReadL(anInput,TStreamTransfer(aMaxLength)).Left();
+	}
+
+EXPORT_C TInt MStreamBuf::Write(const TDesC8& aDes,TRequestStatus& aStatus)
+/** Writes data, asynchronously, from the specified descriptor into the stream buffer; 
+request completion is guaranteed, even if request initiation fails.
+
+The function calls the virtual function DoWriteL(const TDesC8&,TInt,TRequestStatus&) 
+to implement this behaviour. The maximum number of bytes to be written is 
+the value of the maximum length of the descriptor.
+
+@param aDes The source descriptor for the data to be written into the stream 
+buffer.
+@param aStatus The request status that indicates the completion status of this 
+asynchronous request.
+@return The maximum number of bytes to be written, as used in this request. 
+This can be different to the value supplied in aMaxLength; this is dependent 
+on the implementation.
+@see MStreamBuf::DoWriteL() */
+	{
+	return Write(aDes,aDes.Length(),aStatus);
+	}
+
+EXPORT_C TInt MStreamBuf::Write(const TDesC8& aDes,TInt aMaxLength,TRequestStatus& aStatus)
+//
+// Write up to aMaxLength bytes with guaranteed completion.
+//
+	{
+	TInt len=0;
+	TRAPD(r,len=DoWriteL(aDes,aMaxLength,aStatus));
+	if (r!=KErrNone)
+		{
+		TRequestStatus* stat=&aStatus;
+		User::RequestComplete(stat,r);
+		}
+	return len;
+	}
+
+EXPORT_C TInt MStreamBuf::WriteL(const TDesC8& aDes,TRequestStatus& aStatus)
+/** Writes data, asynchronously, from the specified descriptor into the stream buffer.
+
+The function calls the virtual function DoWriteL(const TDesC8&,TInt,TRequestStatus&) 
+to implement this behaviour. The maximum number of bytes to be written is 
+the value of the maximum length of the descriptor.
+
+If the function leaves, then no write request will have been initiated.
+
+@param aDes The source descriptor for the data to be written into the stream 
+buffer.
+@param aStatus The request status that indicates the completion status of this 
+asynchronous request.
+@return The maximum number of bytes to be written, as used in this request. 
+This can be different to the maximum length of the descriptor; this is dependent 
+on the implementation.
+@see MStreamBuf::DoWriteL() */
+	{
+	return DoWriteL(aDes,aDes.Length(),aStatus);
+	}
+
+EXPORT_C TInt MStreamBuf::WriteL(MStreamOutput& anOutput,TInt aMaxLength)
+/** Writes data into the stream buffer from the specified data source.
+
+The function calls the virtual function DoWriteL(MStreamOutput&,TStreamTransfer) 
+to implement this behaviour.
+
+@param anOutput The data source for the write operation.
+@param aMaxLength The maximum amount of data available to be written.
+@return The amount of data that was not consumed. */
+	{
+	return aMaxLength-DoWriteL(anOutput,TStreamTransfer(aMaxLength)).Left();
+	}
+
+EXPORT_C void MStreamBuf::DoRelease()
+/** Frees resources before abandoning the stream buffer.
+
+It is called by Release().
+
+This implementation is empty, but classes derived from MStreamBuf can provide 
+their own implementation, if necessary.
+
+@see MStreamBuf::Release() */
+	{}
+
+EXPORT_C void MStreamBuf::DoSynchL()
+/** Synchronises the stream buffer with the stream, leaving if any error occurs.
+
+In effect, this ensures that buffered data is delivered to the stream.
+
+It is called by SynchL().
+
+This implementation is empty, but classes derived from MStreamBuf can provide 
+their own implementation, if necessary.
+
+@see MStreamBuf::SynchL() */
+	{}
+
+EXPORT_C TInt MStreamBuf::DoReadL(TAny*,TInt)
+//
+// Cannot read from this stream buffer.
+//
+	{
+	Panic(EStreamCannotRead);
+	return TInt();
+	}
+
+EXPORT_C TInt MStreamBuf::DoReadL(TDes8& aDes,TInt aMaxLength,TRequestStatus& aStatus)
+/** Reads data from the stream buffer into the specified descriptor.
+
+This function is called by ReadL(TDes8&,TInt,TRequestStatus&).
+
+This implementation deals with the request synchronously, and completes the 
+request with KErrNone. Other implementations may choose to deal with this 
+in a true asynchronous manner.
+
+In addition, the read operation itself uses the DoReadL(TAny*,TInt) variant.
+
+@param aDes The target descriptor for the data read from the stream buffer. 
+On return, the length of the descriptor is set to the number of bytes read 
+from the stream buffer.
+@param aMaxLength The maximum number of bytes to be read. This value must not 
+be greater than the maximum length of the descriptor, otherwise the function 
+raises a STORE-Stream 2 panic.
+@param aStatus The request status that indicates the completion status of this 
+asynchronous request.
+@return The maximum number of bytes to be read, as used in this request. This 
+implementation uses, and returns, the value supplied in aMaxLength. Other 
+implementations may choose to use a different value.
+@see MStreamBuf::ReadL() */
+	{
+	__ASSERT_DEBUG(aMaxLength<=aDes.MaxLength(),Panic(EStreamReadBeyondEnd));
+	aDes.SetLength(DoReadL((TUint8*)aDes.Ptr(),aMaxLength));
+	TRequestStatus* stat=&aStatus;
+	User::RequestComplete(stat,KErrNone);
+	return aMaxLength;
+	}
+
+EXPORT_C TStreamTransfer MStreamBuf::DoReadL(MStreamInput& anInput,TStreamTransfer aTransfer)
+/** Reads data from the stream into the specified data sink.
+
+It is called by ReadL(MStreamInput&,TStreamTransfer).
+
+This implementation calls the sink's ReadFromL() function, which performs 
+the read (transfer) operation.
+
+This implementation of DoReadL() is called for streams that do not have buffering 
+capabilities, and that are derived directly from this class.
+
+@param anInput The target data sink.
+@param aTransfer A stream transfer object defining the amount of data available 
+to be read.
+@return A stream transfer object defining the amount of data that was not consumed.
+@see MStreamInput::ReadFromL() */
+	{
+	return anInput.ReadFromL(*this,aTransfer);
+	}
+
+EXPORT_C void MStreamBuf::DoWriteL(const TAny*,TInt)
+//
+// Cannot write to this stream buffer.
+//
+	{
+	Panic(EStreamCannotWrite);
+	}
+
+EXPORT_C TInt MStreamBuf::DoWriteL(const TDesC8& aDes,TInt aMaxLength,TRequestStatus& aStatus)
+/** Writes data from the specified descriptor into this stream buffer.
+
+This function is called by WriteL(const TDesC8&,TInt,TRequestStatus&).
+
+This implementation deals with the request synchronously, and completes the 
+request with KErrNone. Other implementations may choose to deal with this 
+in a true asynchronous manner.
+
+In addition, the write operation itself uses the DoWriteL(TAny*,TInt) variant.
+
+@param aDes The source descriptor for the data to be written into the stream 
+buffer.
+@param aMaxLength The number of bytes to be written. This value must not be 
+greater than the maximum length of the descriptor, otherwise the function 
+raises a STORE-Stream 6 panic.
+@param aStatus The request status that indicates the completion status of this 
+asynchronous request.
+@return The maximum number of bytes to be written, as used in this request. 
+This implementation uses, and returns, the value supplied in aMaxLength. Other 
+implementations may choose to use a different value.
+@see MStreamBuf::WriteL() */
+	{
+	__ASSERT_DEBUG(aMaxLength<=aDes.Length(),Panic(EStreamWriteBeyondEnd));
+	DoWriteL(aDes.Ptr(),aMaxLength);
+	TRequestStatus* stat=&aStatus;
+	User::RequestComplete(stat,KErrNone);
+	return aMaxLength;
+	}
+
+EXPORT_C TStreamTransfer MStreamBuf::DoWriteL(MStreamOutput& anOutput,TStreamTransfer aTransfer)
+//
+// Default implementation turning around to anOutput.
+//
+	{
+	return anOutput.WriteToL(*this,aTransfer);
+	}
+
+EXPORT_C TStreamPos MStreamBuf::DoSeekL(TMark,TStreamLocation,TInt)
+//
+// This stream buffer does not support seeking.
+//
+	{
+	Panic(EStreamCannotSeek);
+	TStreamPos streamPos(-1);
+	return streamPos;
+	}
+
+EXPORT_C TStreamBuf::TStreamBuf()
+	: iRPtr(NULL),iREnd(NULL),iWPtr(NULL),iWEnd(NULL)
+/** Sets the pointers that mark out the read and write areas within the intermediate 
+buffer to null. */
+	{}
+
+EXPORT_C void TStreamBuf::SetBuf(TArea anArea,TUint8* aPtr,TUint8* anEnd)
+/** Sets the start and end points of the read and/or the write area within the intermediate 
+buffer.
+
+A start point is always within an area; an end point is always the first byte 
+beyond the end of an area.
+
+@param anArea The areas within the intermediate buffer for which the start 
+and end points are to be set. These can be the read area and/or the write 
+area, as indicated by the ERead and EWrite bits. Only these bits can be set, 
+otherwise the function raises a STORE-Stream 17 panic.
+@param aPtr The start point.
+@param anEnd The end point.
+@see MStreamBuf::TRead
+@see MStreamBuf::TWrite */
+	{
+	__ASSERT_ALWAYS(!(anArea&~(ERead|EWrite)),Panic(EStreamAreaInvalid));
+	if (anArea&ERead)
+		SetBuf(ERead,aPtr,anEnd);
+	if (anArea&EWrite)
+		SetBuf(EWrite,aPtr,anEnd);
+	}
+
+EXPORT_C void TStreamBuf::SetPtr(TArea anArea,TUint8* aPtr)
+/** Sets the start point of the read and/or the write area within the intermediate 
+buffer.
+
+A start point is always within an area.
+
+@param anArea The areas within the intermediate buffer for which the start 
+point is to be set. These can be the read area and/or the write area, as indicated 
+by the ERead and EWrite bits. Only these bits can be set, otherwise the function 
+raises a STORE-Stream 17 panic.
+@param aPtr The start point.
+@see MStreamBuf::TRead
+@see MStreamBuf::TWrite */
+	{
+	__ASSERT_ALWAYS(!(anArea&~(ERead|EWrite)),Panic(EStreamAreaInvalid));
+	if (anArea&ERead)
+		SetPtr(ERead,aPtr);
+	if (anArea&EWrite)
+		SetPtr(EWrite,aPtr);
+	}
+
+EXPORT_C void TStreamBuf::SetEnd(TArea anArea,TUint8* anEnd)
+//
+// Set the end pointer for the buffer area(s) indicated by anArea.
+//
+	{
+	__ASSERT_ALWAYS(!(anArea&~(ERead|EWrite)),Panic(EStreamAreaInvalid));
+	if (anArea&ERead)
+		SetEnd(ERead,anEnd);
+	if (anArea&EWrite)
+		SetEnd(EWrite,anEnd);
+	}
+
+EXPORT_C TUint8* TStreamBuf::Ptr(TArea anArea) const
+/** Gets the current start point of the read or write area within the intermediate 
+buffer.
+
+@param anArea The area within the intermediate buffer for which the start 
+point is to be fetched. This can be either the read area or the write area, 
+as indicated by the ERead and EWrite bits. Only one of these can be set, otherwise 
+the function raises a STORE-Stream 17 panic.
+@return The start point.
+@see MStreamBuf::TRead
+@see MStreamBuf::TWrite */
+	{
+	if (anArea==ERead)
+		return Ptr(ERead);
+//
+	__ASSERT_ALWAYS(anArea==EWrite,Panic(EStreamAreaInvalid));
+	return Ptr(EWrite);
+	}
+
+EXPORT_C TUint8* TStreamBuf::End(TArea anArea) const
+/** Gets the current end point of the read or write area within the intermediate 
+buffer.
+
+An end point is always the first byte beyond the end of an area.
+
+@param anArea The area within the intermediate buffer for which the end point 
+is to be fetched. This can be either the read area or the write area, as indicated 
+by the ERead and EWrite bits. Only one of these can be set, otherwise the 
+function raises a STORE-Stream 17 panic.
+@return The end point. */
+	{
+	if (anArea==ERead)
+		return End(ERead);
+//
+	__ASSERT_ALWAYS(anArea==EWrite,Panic(EStreamAreaInvalid));
+	return End(EWrite);
+	}
+
+EXPORT_C TInt TStreamBuf::Avail(TArea anArea) const
+/** Gets the number of bytes available in the read or write area within the intermediate 
+buffer.
+
+@param anArea The area within the intermediate buffer for which the number 
+of available bytes is to be fetched. This can be either the read area or the 
+write area, as indicated by the ERead and EWrite bits. Only one of these can 
+be set, otherwise the function raises a STORE-Stream 17 panic.
+@return The number of bytes available. */
+	{
+	if (anArea==ERead)
+		return Avail(ERead);
+//
+	__ASSERT_ALWAYS(anArea==EWrite,Panic(EStreamAreaInvalid));
+	return Avail(EWrite);
+	}
+
+EXPORT_C TInt TStreamBuf::DoReadL(TAny* aPtr,TInt aMaxLength)
+/** Reads data from the intermediate buffer into the specified memory location.
+
+The function calls the virtual function UnderfLowL() to give concrete implementations 
+the chance to refill the intermediate buffer, and satisfy the caller's requirements.
+
+This implementation overrides the one supplied by the base class MStreamBuf, 
+and is called by, MStreamBuf::ReadL(TAny*,TInt).
+
+@param aPtr A pointer to the target memory location for the data read from 
+the intermediate buffer.
+@param aMaxLength The maximum number of bytes to be read.
+@return The number of bytes read. This may be less than the amount requested.
+@see MStreamBuf::ReadL()
+@see MStreamBuf::DoReadL() */
+	{
+	__ASSERT_DEBUG(aMaxLength>=0,Panic(EStreamReadLengthNegative));
+	__ASSERT_DEBUG(aMaxLength>0,Panic(EStreamReadNoTransfer));
+	__ASSERT_DEBUG(Ptr(ERead)!=NULL||End(ERead)==NULL,Panic(EStreamCannotRead));
+	TInt left=aMaxLength;
+	TInt avail=Avail(ERead);
+	__ASSERT_DEBUG(avail>=0,User::Invariant());
+	if (avail==0)
+		goto underflow;
+//
+	do
+		{
+		__ASSERT_DEBUG(avail==Avail(ERead),Panic(EStreamUnderflowInBreach));
+		__ASSERT_DEBUG(left>0&&avail>0,User::Invariant());
+		{
+		TInt len=Min(left,avail);
+		TUint8* ptr=Ptr(ERead);
+		aPtr=Mem::Copy(aPtr,ptr,len);
+		SetPtr(ERead,ptr+len);
+		left-=len;
+		if (left==0)
+			return aMaxLength; // that's it
+		}
+//
+	underflow:
+		avail=UnderflowL(left);
+		} while (avail>0);
+	__ASSERT_DEBUG(avail==0&&Avail(ERead)==0,Panic(EStreamUnderflowInBreach));
+	return aMaxLength-left;
+	}
+
+EXPORT_C TStreamTransfer TStreamBuf::DoReadL(MStreamInput& anInput,TStreamTransfer aTransfer)
+/** Reads data from the intermediate buffer and, if necessary, any remaining data 
+from the stream to the specified target stream input object.
+
+It is called by ReadL(MStreamInput&,TStreamTransfer).
+
+The intermediate buffer is emptied first by calling the target stream input's 
+PushL() function, which performs the read from intermediate buffer operation. 
+Any remaining data is then read from the stream by calling the target stream 
+object's ReadFromL() function, which performs the read from stream operation.
+
+This implementation is called for streams that have buffering capabilities 
+and are derived from this class.
+
+@param anInput The target stream input object. 
+@param aTransfer A stream transfer object defining the amount of data available 
+to be written.
+@return The amount of data that was not consumed.
+@see MStreamInput::ReadFromL()
+@see MStreamInput::PushL() */
+	{
+	__ASSERT_DEBUG(aTransfer>0,Panic(EStreamReadNoTransfer));
+	__ASSERT_DEBUG(Ptr(ERead)!=NULL||End(ERead)==NULL,Panic(EStreamCannotRead));
+	__ASSERT_DEBUG(Avail(ERead)>=0,User::Invariant());
+	TInt len=aTransfer[Avail(ERead)];
+	if (len>0)
+		{
+		__DEBUG(TInt avail=Avail(ERead)); // may be pushing into this streambuf
+		TUint8* ptr=Ptr(ERead);
+		len=anInput.PushL(ptr,len);
+		__ASSERT_DEBUG(len>=0&&len<=aTransfer[avail]&&Ptr(ERead)==ptr&&Avail(ERead)>=avail,Panic(EStreamPushInBreach));
+		SetPtr(ERead,ptr+len);
+		aTransfer-=len;
+		}
+	if (aTransfer>0)
+		aTransfer=anInput.ReadFromL(*this,aTransfer);
+	return aTransfer;
+	}
+
+EXPORT_C void TStreamBuf::DoWriteL(const TAny* aPtr,TInt aLength)
+/** Writes data from the specified memory location into the intermediate buffer.
+
+The function calls the virtual function OverfLowL() to give concrete implementations 
+the chance to forward the intermediate buffer content to its destination.
+
+This implementation overrides the one supplied by the base class MStreamBuf, 
+and is called by MStreamBuf::WriteL(const TAny*,TInt).
+
+@param aPtr A pointer to the source memory location for the data to be written 
+to the intermediate buffer.
+@param aLength The number of bytes to be written.
+@return The number of bytes written.
+@see MStreamBuf::WriteL()
+@see MStreamBuf::DoWriteL() */
+	{
+	__ASSERT_DEBUG(aLength>=0,Panic(EStreamWriteLengthNegative));
+	__ASSERT_DEBUG(aLength>0,Panic(EStreamWriteNoTransfer));
+	__ASSERT_DEBUG(Ptr(EWrite)!=NULL||End(EWrite)==NULL,Panic(EStreamCannotWrite));
+	TInt avail=Avail(EWrite);
+	__ASSERT_DEBUG(avail>=0,User::Invariant());
+	if (avail==0)
+		goto overflow;
+//
+	for(;;)
+		{
+		__ASSERT_DEBUG(avail>0,Panic(EStreamOverflowInBreach));
+		__ASSERT_DEBUG(aLength>0,User::Invariant());
+		{
+		TInt len=Min(aLength,avail);
+		SetPtr(EWrite,Mem::Copy(Ptr(EWrite),aPtr,len));
+		aLength-=len;
+		if (aLength==0)
+			return; // done
+//
+		aPtr=(TUint8*)aPtr+len;
+		}
+//
+	overflow:
+		OverflowL();
+		avail=Avail(EWrite);
+		};
+	}
+
+EXPORT_C TStreamTransfer TStreamBuf::DoWriteL(MStreamOutput& anOutput,TStreamTransfer aTransfer)
+//
+// Default implementation filling the buffer before turning around to anOutput.
+//
+	{
+	__ASSERT_DEBUG(aTransfer>0,Panic(EStreamWriteNoTransfer));
+	__ASSERT_DEBUG(Ptr(EWrite)!=NULL||End(EWrite)==NULL,Panic(EStreamCannotWrite));
+	__ASSERT_DEBUG(Avail(EWrite)>=0,User::Invariant());
+	TInt len=aTransfer[Avail(EWrite)];
+	if (len>0)
+		{
+		__DEBUG(TInt avail=Avail(EWrite)); // may be pulling from this streambuf
+		TUint8* ptr=Ptr(EWrite);
+		len=anOutput.PullL(ptr,len);
+		__ASSERT_DEBUG(len>=0&&len<=aTransfer[avail]&&Ptr(EWrite)==ptr&&Avail(EWrite)>=avail,Panic(EStreamPullInBreach));
+		SetPtr(EWrite,ptr+len);
+		aTransfer-=len;
+		}
+	if (aTransfer>0)
+		aTransfer=anOutput.WriteToL(*this,aTransfer);
+	return aTransfer;
+	}
+