sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: //
sl@0: 
sl@0: #include "US_STD.H"
sl@0: 
sl@0: #define UNUSED_VAR(a) a = a
sl@0: 
sl@0: EXPORT_C TInt TStreamMark::ReadL(TStreamExchange& aHost,TDes8& aDes,TRequestStatus& aStatus)
sl@0: //
sl@0: // Read asynchronously.
sl@0: //
sl@0: 	{
sl@0: 	return aHost.DoReadL(aDes,aDes.MaxLength(),aStatus,*this);
sl@0: 	}
sl@0: 
sl@0: EXPORT_C TInt TStreamMark::WriteL(TStreamExchange& aHost,const TDesC8& aDes,TRequestStatus& aStatus)
sl@0: /** Writes data, asynchronously, from the specified descriptor into the shared 
sl@0: stream.
sl@0: 
sl@0: The maximum number of bytes to be written is the value of the maximum length 
sl@0: of the descriptor.
sl@0: 
sl@0: If the function leaves, then no write request will have been initiated.
sl@0: 
sl@0: @param aHost The object that manages shared streaming.
sl@0: @param aDes The source descriptor for the data to be written into the shared 
sl@0: stream.
sl@0: @param aStatus The request status that indicates the completion status of this 
sl@0: asynchronous request.
sl@0: @return The maximum number of bytes to be written, as used in this request. 
sl@0: This can be different to the maximum length of the descriptor; this is dependent 
sl@0: on the implementation. */
sl@0: 	{
sl@0: 	return aHost.DoWriteL(aDes,aDes.Length(),aStatus,*this);
sl@0: 	}
sl@0: 
sl@0: EXPORT_C MStreamBuf* TStreamExchange::Host()
sl@0: /** Gets a pointer to the stream buffer that acts as the shared host.
sl@0: 
sl@0: The function refreshes the active read/write marks and gives the caller exclusive 
sl@0: use of the shared host.
sl@0: 
sl@0: @return A pointer to a stream buffer that acts as shared host. */
sl@0: 	{
sl@0: 	__ASSERT_DEBUG((iRMrk==NULL||iRMrk!=iWMrk&&iRMrk->IsTracking(iRMrk))&&(iWMrk==NULL||iWMrk->IsTracking(iWMrk)),User::Invariant());
sl@0: 	if (iRMrk!=NULL)
sl@0: 		{
sl@0: 		TRAPD(ignore,*iRMrk=Buf().TellL(MStreamBuf::ERead));
sl@0:         UNUSED_VAR(ignore);
sl@0: 		iRMrk=NULL;
sl@0: 		}
sl@0: 	if (iWMrk!=NULL)
sl@0: 		{
sl@0: 		TRAPD(ignore,*iWMrk=Buf().TellL(MStreamBuf::EWrite));
sl@0:         UNUSED_VAR(ignore);
sl@0: 		iWMrk=NULL;
sl@0: 		}
sl@0: 	return iHost;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C MStreamBuf* TStreamExchange::HostL()
sl@0: /** Gets a pointer to the stream buffer that acts as the shared host, and leaves 
sl@0: if this object is not active.
sl@0: 
sl@0: The function refreshes the active read/write marks and gives the caller exclusive 
sl@0: use of the shared host.
sl@0: 
sl@0: @return A pointer to a stream buffer that acts as shared host.
sl@0: @see IsActive() */
sl@0: 	{
sl@0: 	MStreamBuf* host=Host();
sl@0: 	if (host==NULL)
sl@0: 		__LEAVE(KErrNotReady);
sl@0: 	return host;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C void TStreamExchange::Release()
sl@0: /** Releases the reference to the shared host, and drops any active read or write 
sl@0: marks. */
sl@0: 	{
sl@0: 	__ASSERT_DEBUG((iRMrk==NULL||iRMrk!=iWMrk&&iRMrk->IsTracking(iRMrk))&&(iWMrk==NULL||iWMrk->IsTracking(iWMrk)),User::Invariant());
sl@0: 	iHost=NULL;
sl@0: 	iRMrk=NULL;
sl@0: 	iWMrk=NULL;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C TInt TStreamExchange::SizeL() const
sl@0: /** Gets the size of the shared host buffer.
sl@0: 
sl@0: @return The size of the shared host buffer. */
sl@0: 	{
sl@0: 	return BufL().SizeL();
sl@0: 	}
sl@0: 
sl@0: EXPORT_C TBool TStreamExchange::RefersTo(const TStreamMark& aMark)
sl@0: //
sl@0: // Return whether aMark is referred to.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG((iRMrk==NULL||iRMrk!=iWMrk&&iRMrk->IsTracking(iRMrk))&&(iWMrk==NULL||iWMrk->IsTracking(iWMrk)),User::Invariant());
sl@0: 	return iRMrk==aMark||iWMrk==aMark;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C void TStreamExchange::Drop(const TStreamMark& aMark)
sl@0: //
sl@0: // Drop any reference to aMark.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG((iRMrk==NULL||iRMrk!=iWMrk&&iRMrk->IsTracking(iRMrk))&&(iWMrk==NULL||iWMrk->IsTracking(iWMrk)),User::Invariant());
sl@0: 	if (iRMrk==aMark)
sl@0: 		iRMrk=NULL;
sl@0: 	else if (iWMrk==aMark)
sl@0: 		iWMrk=NULL;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C void TStreamExchange::GetL(TStreamMark& aMark)
sl@0: //
sl@0: // Refresh and drop any reference to aMark.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG((iRMrk==NULL||iRMrk!=iWMrk&&iRMrk->IsTracking(iRMrk))&&(iWMrk==NULL||iWMrk->IsTracking(iWMrk)),User::Invariant());
sl@0: 	if (iRMrk==aMark)
sl@0: 		{
sl@0: 		iRMrk=NULL;
sl@0: 		aMark=Buf().TellL(MStreamBuf::ERead);
sl@0: 		}
sl@0: 	else if (iWMrk==aMark)
sl@0: 		{
sl@0: 		iWMrk=NULL;
sl@0: 		aMark=Buf().TellL(MStreamBuf::EWrite);
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: EXPORT_C TInt TStreamExchange::DoReadL(TAny* aPtr,TInt aMaxLength,TStreamMark& aMark)
sl@0: //
sl@0: // Read up to aMaxLength bytes starting at aMark.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iWMrk==NULL||iWMrk!=iRMrk&&iWMrk->IsTracking(iWMrk),User::Invariant());
sl@0: 	if (iRMrk!=aMark)
sl@0: 		return PrepareAndReadL(aPtr,aMaxLength,aMark);
sl@0: //
sl@0: 	__ASSERT_DEBUG(aMark.IsTracking(iRMrk),User::Invariant());
sl@0: 	iRMrk=NULL;
sl@0: 	TInt len=Buf().ReadL(aPtr,aMaxLength);
sl@0: 	iRMrk=aMark;
sl@0: 	return len;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C TInt TStreamExchange::DoReadL(TDes8& aDes,TInt aMaxLength,TRequestStatus& aStatus,TStreamMark& aMark)
sl@0: //
sl@0: // Read up to aMaxLength bytes asynchronously.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iWMrk==NULL||iWMrk!=iRMrk&&iWMrk->IsTracking(iWMrk),User::Invariant());
sl@0: 	if (iRMrk!=aMark)
sl@0: 		return PrepareAndReadL(aDes,aMaxLength,aStatus,aMark);
sl@0: //
sl@0: 	__ASSERT_DEBUG(aMark.IsTracking(iRMrk),User::Invariant());
sl@0: 	iRMrk=NULL;
sl@0: 	TInt len=Buf().ReadL(aDes,aMaxLength,aStatus);
sl@0: 	iRMrk=aMark;
sl@0: 	return len;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C TStreamTransfer TStreamExchange::DoReadL(MStreamInput& anInput,TStreamTransfer aTransfer,TStreamMark& aMark)
sl@0: //
sl@0: // Push up to aTransfer bytes into anInput, starting at aMark.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iWMrk==NULL||iWMrk!=iRMrk&&iWMrk->IsTracking(iWMrk),User::Invariant());
sl@0: 	if (iRMrk!=aMark)
sl@0: 		return PrepareAndReadL(anInput,aTransfer,aMark);
sl@0: //
sl@0: 	__ASSERT_DEBUG(aMark.IsTracking(iRMrk),User::Invariant());
sl@0: 	iRMrk=NULL;
sl@0: 	TStreamTransfer trans=Buf().ReadL(anInput,aTransfer);
sl@0: 	iRMrk=aMark;
sl@0: 	return trans;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C void TStreamExchange::DoWriteL(const TAny* aPtr,TInt aLength,TStreamMark& aMark)
sl@0: //
sl@0: // Write aLength bytes starting at aMark.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iRMrk==NULL||iRMrk!=iWMrk&&iRMrk->IsTracking(iRMrk),User::Invariant());
sl@0: 	if (iWMrk==aMark)
sl@0: 		{
sl@0: 		__ASSERT_DEBUG(aMark.IsTracking(iWMrk),User::Invariant());
sl@0: 		iWMrk=NULL;
sl@0: 		Buf().WriteL(aPtr,aLength);
sl@0: 		iWMrk=aMark;
sl@0: 		}
sl@0: 	else
sl@0: 		PrepareAndWriteL(aPtr,aLength,aMark);
sl@0: 	}
sl@0: 
sl@0: EXPORT_C TInt TStreamExchange::DoWriteL(const TDesC8& aDes,TInt aMaxLength,TRequestStatus& aStatus,TStreamMark& aMark)
sl@0: //
sl@0: // Write up to aMaxLength bytes asynchronously.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iRMrk==NULL||iRMrk!=iWMrk&&iRMrk->IsTracking(iRMrk),User::Invariant());
sl@0: 	if (iWMrk!=aMark)
sl@0: 		return PrepareAndWriteL(aDes,aMaxLength,aStatus,aMark);
sl@0: //
sl@0: 	__ASSERT_DEBUG(aMark.IsTracking(iWMrk),User::Invariant());
sl@0: 	iWMrk=NULL;
sl@0: 	TInt len=Buf().WriteL(aDes,aMaxLength,aStatus);
sl@0: 	iWMrk=aMark;
sl@0: 	return len;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C TStreamTransfer TStreamExchange::DoWriteL(MStreamOutput& anOutput,TStreamTransfer aTransfer,TStreamMark& aMark)
sl@0: //
sl@0: // Pull up to aTransfer bytes from anOutput, starting at aMark.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iRMrk==NULL||iRMrk!=iWMrk&&iRMrk->IsTracking(iRMrk),User::Invariant());
sl@0: 	if (iWMrk!=aMark)
sl@0: 		return PrepareAndWriteL(anOutput,aTransfer,aMark);
sl@0: //
sl@0: 	__ASSERT_DEBUG(aMark.IsTracking(iWMrk),User::Invariant());
sl@0: 	iWMrk=NULL;
sl@0: 	TStreamTransfer trans=Buf().WriteL(anOutput,aTransfer);
sl@0: 	iWMrk=aMark;
sl@0: 	return trans;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C TStreamPos TStreamExchange::DoSeekL(TStreamMark& aMark,TStreamLocation aLocation,TInt anOffset)
sl@0: //
sl@0: // Position aMark at anOffset from aLocation.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG((iRMrk==NULL||iRMrk!=iWMrk&&iRMrk->IsTracking(iRMrk))&&(iWMrk==NULL||iWMrk->IsTracking(iWMrk)),User::Invariant());
sl@0: 	if (iRMrk==aMark)
sl@0: 		{
sl@0: 		iRMrk=NULL;
sl@0: 		TStreamPos pos=Buf().SeekL(MStreamBuf::ERead,aLocation,anOffset);
sl@0: 		iRMrk=aMark;
sl@0: 		return pos;
sl@0: 		}
sl@0: //
sl@0: 	if (iWMrk==aMark)
sl@0: 		{
sl@0: 		iWMrk=NULL;
sl@0: 		TStreamPos pos=Buf().SeekL(MStreamBuf::EWrite,aLocation,anOffset);
sl@0: 		iWMrk=aMark;
sl@0: 		return pos;
sl@0: 		}
sl@0: //
sl@0: 	return MarkSeekL(aMark,aLocation,anOffset);
sl@0: 	}
sl@0: 
sl@0: void TStreamExchange::PrepareForReadingL(TStreamMark& aMark)
sl@0: //
sl@0: // Prepare the host buffer to start reading at aMark.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iRMrk==NULL||iRMrk->IsTracking(iRMrk),User::Invariant());
sl@0: 	if (iWMrk==aMark)
sl@0: 		{
sl@0: 		iWMrk=NULL;
sl@0: 		aMark=Buf().TellL(MStreamBuf::EWrite);
sl@0: 		}
sl@0: 	else if (aMark.IsEmpty())
sl@0: 		__LEAVE(KErrNotReady);
sl@0: //
sl@0: 	if (iRMrk!=NULL)
sl@0: 		{
sl@0: 		TRAPD(ignore,*iRMrk=Buf().TellL(MStreamBuf::ERead));
sl@0:         UNUSED_VAR(ignore);
sl@0: 		iRMrk=NULL;
sl@0: 		}
sl@0: //
sl@0: 	TStreamPos pos=aMark.Position();
sl@0: 	aMark.Track(iRMrk);
sl@0: 	BufL().SeekL(MStreamBuf::ERead,pos);
sl@0: 	}
sl@0: 
sl@0: void TStreamExchange::PrepareForWritingL(TStreamMark& aMark)
sl@0: //
sl@0: // Prepare the host buffer to start writing at aMark.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iWMrk==NULL||iWMrk->IsTracking(iWMrk),User::Invariant());
sl@0: 	if (iRMrk==aMark)
sl@0: 		{
sl@0: 		iRMrk=NULL;
sl@0: 		aMark=Buf().TellL(MStreamBuf::ERead);
sl@0: 		}
sl@0: 	else if (aMark.IsEmpty())
sl@0: 		__LEAVE(KErrNotReady);
sl@0: //
sl@0: 	if (iWMrk!=NULL)
sl@0: 		{
sl@0: 		TRAPD(ignore,*iWMrk=Buf().TellL(MStreamBuf::EWrite));
sl@0:         UNUSED_VAR(ignore);
sl@0: 		iWMrk=NULL;
sl@0: 		}
sl@0: //
sl@0: 	TStreamPos pos=aMark.Position();
sl@0: 	aMark.Track(iWMrk);
sl@0: 	BufL().SeekL(MStreamBuf::EWrite,pos);
sl@0: 	}
sl@0: 
sl@0: TInt TStreamExchange::PrepareAndReadL(TAny* aPtr,TInt aMaxLength,TStreamMark& aMark)
sl@0: 	{
sl@0: 	PrepareForReadingL(aMark);
sl@0: 	TInt len=Buf().ReadL(aPtr,aMaxLength);
sl@0: 	iRMrk=aMark;
sl@0: 	return len;
sl@0: 	}
sl@0: 
sl@0: TInt TStreamExchange::PrepareAndReadL(TDes8& aDes,TInt aMaxLength,TRequestStatus& aStatus,TStreamMark& aMark)
sl@0: 	{
sl@0: 	PrepareForReadingL(aMark);
sl@0: 	TInt len=Buf().ReadL(aDes,aMaxLength,aStatus);
sl@0: 	iRMrk=aMark;
sl@0: 	return len;
sl@0: 	}
sl@0: 
sl@0: TStreamTransfer TStreamExchange::PrepareAndReadL(MStreamInput& anInput,TStreamTransfer aTransfer,TStreamMark& aMark)
sl@0: 	{
sl@0: 	PrepareForReadingL(aMark);
sl@0: 	TStreamTransfer trans=Buf().ReadL(anInput,aTransfer);
sl@0: 	iRMrk=aMark;
sl@0: 	return trans;
sl@0: 	}
sl@0: 
sl@0: void TStreamExchange::PrepareAndWriteL(const TAny* aPtr,TInt aLength,TStreamMark& aMark)
sl@0: 	{
sl@0: 	PrepareForWritingL(aMark);
sl@0: 	Buf().WriteL(aPtr,aLength);
sl@0: 	iWMrk=aMark;
sl@0: 	}
sl@0: 
sl@0: TInt TStreamExchange::PrepareAndWriteL(const TDesC8& aDes,TInt aMaxLength,TRequestStatus& aStatus,TStreamMark& aMark)
sl@0: 	{
sl@0: 	PrepareForWritingL(aMark);
sl@0: 	TInt len=Buf().WriteL(aDes,aMaxLength,aStatus);
sl@0: 	iWMrk=aMark;
sl@0: 	return len;
sl@0: 	}
sl@0: 
sl@0: TStreamTransfer TStreamExchange::PrepareAndWriteL(MStreamOutput& anOutput,TStreamTransfer aTransfer,TStreamMark& aMark)
sl@0: 	{
sl@0: 	PrepareForWritingL(aMark);
sl@0: 	TStreamTransfer trans=Buf().WriteL(anOutput,aTransfer);
sl@0: 	iWMrk=aMark;
sl@0: 	return trans;
sl@0: 	}
sl@0: 
sl@0: TStreamPos TStreamExchange::MarkSeekL(TStreamMark& aMark,TStreamLocation aLocation,TInt anOffset)
sl@0: 	{
sl@0: 	if (aLocation==EStreamMark)
sl@0: 		{
sl@0: 		if (aMark.IsEmpty())
sl@0: 			__LEAVE(KErrNotReady);
sl@0: //
sl@0: 		aLocation=EStreamBeginning;
sl@0: 		anOffset+=aMark.Position().Offset();
sl@0: 		}
sl@0: 	aMark.Clear();
sl@0: 	TStreamPos pos=BufL().SeekL(0,aLocation,anOffset);
sl@0: 	aMark=pos;
sl@0: 	return pos;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C void TStreamMark::__DbgChkPos(TStreamPos aPos)
sl@0: //
sl@0: // Check for a negative position.
sl@0: //
sl@0: 	{
sl@0: 	__ASSERT_ALWAYS(aPos>=KStreamBeginning,Panic(EStreamPosInvalid));
sl@0: 	}
sl@0: