genericopenlibs/openenvcore/backend/src/corebackend/uredirdesc.cpp
changeset 0 e4d67989cc36
child 25 7701629b34a6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/openenvcore/backend/src/corebackend/uredirdesc.cpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,327 @@
+// Copyright (c) 2006-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 <errno.h>
+#include "fdesc.h"
+
+CRedirDesc::CRedirDesc() : CFileDescBase(O_RDWR)
+	{
+	iReadNone = EFalse;
+	iWriteNone = EFalse;
+	iStatus = ENotConnected;
+	iLock.CreateLocal();
+	}
+// -----------------------------------------------------------------------------
+// CRedirDesc::Configure
+// Implementation for Configure the Media i.e. connect to stdio server
+// -----------------------------------------------------------------------------
+//
+TInt CRedirDesc::Configure()
+	{
+	TInt ret;
+	TBuf8<1> aDes;
+	iStatus = ENoServer;
+	ret = iSession.Connect(); 
+	if( KErrNone  == ret)
+		{
+		ret = iSession.CheckMedia(aDes);
+		if( KErrNone == ret)
+			{
+			iStatus = EConnected;
+			//In case both the media is NONE the server would fail the connection and 
+			//this block of the code in not executed. If any of media either read or 
+			//write in NONE specified in config.ini file then the iReadNone and iWriteNone
+			//flag is set to ETrue which is check in read and write functions.
+			if( !aDes.Compare(_L8("R")) )
+				{
+				iReadNone = ETrue;
+				}
+			else
+				{
+				if( !aDes.Compare(_L8("W")) )
+					{
+					iWriteNone = ETrue;	
+					}
+				}
+			}
+		}
+	return ret;
+	}
+// -----------------------------------------------------------------------------
+// CRedirDesc::Read
+// Implementation for Read
+// -----------------------------------------------------------------------------
+//
+void CRedirDesc::Read(TDes8& aDes, TRequestStatus& aStatus)
+	{
+	if( ENotConnected == iStatus )
+		{
+		iLock.Wait();
+		if( ENotConnected == iStatus )
+			{
+			Configure();	
+			}
+		iLock.Signal();
+		}
+	if( EConnected == iStatus && !iReadNone )
+		{
+		iSession.Read(aStatus, aDes, aDes.MaxLength());
+		}
+	else 
+		{
+		// If no session is there i.e. no server in production code or in the
+		// config.ini file for the stdioserver the both media type is NONE then
+		// just complete the request with EOF so that libc can handle it.
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status, KErrEof);
+		}
+	
+	}
+
+
+TInt CRedirDesc::WriteCompletion(TDes8& aDesc, TInt /*aStatus*/)
+	{
+	return aDesc.Length();
+	}
+	
+TInt CRedirDesc::ReadCompletion(TDes8& aDesc, TInt /*aStatus*/)
+	{
+	return aDesc.Length();
+	}
+
+// -----------------------------------------------------------------------------
+// CRedirDesc::Write
+// Implementation for Write
+// -----------------------------------------------------------------------------
+//
+void CRedirDesc::Write(TDes8& aDesc, TRequestStatus& aStatus)
+	{	
+	if( ENotConnected == iStatus )
+		{
+		iLock.Wait();
+		if( ENotConnected == iStatus )
+			{	
+			Configure();	
+			}
+		iLock.Signal();
+		}
+	if(EConnected  == iStatus && !iWriteNone)
+		{
+		iSession.Write(aStatus, aDesc, aDesc.Length());		
+		}
+	else
+		{
+		// If no session is there i.e. no server in production code or the user
+		// has specified the media type in config.ini file as NONE put the write
+		// data in blackhole and just complete the request as done in Read call.
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status, KErrNone);
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CRedirDesc::Fcntl
+// Implementation for fcntl
+// -----------------------------------------------------------------------------
+//
+TInt CRedirDesc::Fcntl(TUint /*anArg*/, TUint aCmd)
+	{
+	if (aCmd == F_GETFL)
+		{
+		return iFcntlFlag;
+		}
+	return KErrNotSupported;
+	}
+
+// -----------------------------------------------------------------------------
+// CRedirDesc::FinalClose
+// Cleanup function used by FID
+// -----------------------------------------------------------------------------
+//
+TInt CRedirDesc::FinalClose()
+	{
+	iSession.Close();
+	return KErrNone;
+	}
+
+// -----------------------------------------------------------------------------
+// CRedirDesc::Poll
+// checks if that aEvents is ready or not.
+// -----------------------------------------------------------------------------
+//
+TInt CRedirDesc::Poll(TUint aEvents)
+	{
+	TInt readyEvents = 0;
+
+	if ((aEvents & EReadyForWriting ) && !iWriteNone)
+		{
+		readyEvents |= EReadyForWriting;
+		}
+	
+	return readyEvents;
+	}
+	
+// -----------------------------------------------------------------------------
+// CRedirDesc::NotifyActivity
+// registers a notification for read event i.e. when data is ready for read.
+// this function is only for reading because poll itself would return for writing
+// if that media for writing is available.
+// -----------------------------------------------------------------------------
+//
+TInt CRedirDesc::NotifyActivity(TUint aEvents, TRequestStatus& aRequest, TTimeIntervalMicroSeconds32 /* timeout=0 */)
+	{
+	if( ENotConnected == iStatus )
+		{
+		iLock.Wait();
+		if( ENotConnected == iStatus )
+			{
+			Configure();	
+			}
+		iLock.Signal();
+		}
+
+	if(EConnected  != iStatus || aEvents & EReadyForWriting || iReadNone )
+		{
+		//complete aStatus with KErrNone
+		TRequestStatus* status = &aRequest;
+		User::RequestComplete(status, KErrNone);
+		}
+	
+	if ((aEvents & EReadyForReading) && !iReadNone)
+		{		
+		TInt events = 0;
+		events = EReadyForReading;
+		iSession.NotifyActivity((TInt)events, aRequest);
+		}
+	
+	return KErrNone;
+	}
+
+// -----------------------------------------------------------------------------
+// CRedirDesc::TweakReadyEvents
+// Prepares the redir desc specific output events
+// -----------------------------------------------------------------------------
+//
+TInt CRedirDesc::TweakReadyEvents(TInt errval)
+    {
+    TInt returnEvents = 0;
+    // This file descriptor is pipe-like 
+    if( errval >= KErrNone )
+        {
+        returnEvents |= EReadyForReading;
+        returnEvents |= EReadyForWriting;
+        }
+    else
+        {
+        returnEvents |= EAnyException;
+        }
+    return returnEvents;
+    }
+
+// -----------------------------------------------------------------------------
+// CRedirDesc::CancelNotify
+// To cancel notification.
+// -----------------------------------------------------------------------------
+//
+void CRedirDesc::CancelNotify()
+	{
+	if ( iSession.Handle() )
+		{
+		iSession.CancelNotify();
+		}
+	}
+
+//-----------------------------------------------------------------------------
+//int CRedirDesc::SetEcho(TBool aEcho)
+//
+//Sets the echo flag to the given value.
+//-----------------------------------------------------------------------------
+
+int CRedirDesc::SetEcho(TUint8 aEcho)
+	{
+	int err = KErrNone;
+	//start the redirection server if not already started...
+	if( ENotConnected == iStatus )
+		{
+		iLock.Wait();
+		Configure();	
+		iLock.Signal();
+		}	
+	//set the echo flag if the connection with the server is successfull...
+	if(EConnected  == iStatus)
+		{
+		err = iSession.SetEcho(aEcho);
+		}
+	else
+		{
+		// If no session is there i.e. no server in production code or in the
+		// config.ini file for the stdioserver the both media type is NONE then
+		// just return EOF so that libc can handle it.
+		err = KErrEof;
+		}
+	return err;
+	}
+	
+
+// method definitions for CStdErrDesc
+CStdErrDesc::CStdErrDesc() : CFileDescBase(O_RDWR)
+	{
+	// nada
+	}
+
+// -----------------------------------------------------------------------------
+// CStdErrDesc::Write
+// Implementation for Write
+// -----------------------------------------------------------------------------
+//
+void CStdErrDesc::Write(TDes8& aDesc, TRequestStatus& aStatus)
+	{
+	HBufC16* des16 = NULL;
+	TRAPD(err, des16 = HBufC16::NewL(aDesc.Length()));
+	if (err != KErrNone)
+		{
+		//complete aStatus with that error code
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status, err);
+		return;
+		}
+	TPtr16 ptr(des16->Des());
+	ptr.Copy(aDesc);
+	#ifdef _DEBUG
+	RDebug::RawPrint(*des16);
+	#endif //_DEBUG
+	delete des16;
+	TRequestStatus* status = &aStatus;
+	User::RequestComplete(status, KErrNone);
+	}
+
+// -----------------------------------------------------------------------------
+// CStdErrDesc::Fcntl
+// Implementation for fcntl
+// -----------------------------------------------------------------------------
+//
+TInt CStdErrDesc::Fcntl(TUint /*anArg*/, TUint aCmd)
+	{
+	if (aCmd == F_GETFL)
+		{
+		return iFcntlFlag;
+		}
+	return KErrNotSupported;
+	}
+
+TInt CStdErrDesc::WriteCompletion(TDes8& aDesc, TInt /*aStatus*/)
+	{
+	return aDesc.Length();
+	}