genericopenlibs/cstdlib/RedirCli/REDIRCLI.CPP
changeset 31 ce057bb09d0b
parent 0 e4d67989cc36
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     1 // Copyright (c) 1999-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 <e32std.h>
       
    17 #include <redircli.h>
       
    18 #include <redircliinternal.h>
       
    19 
       
    20 #ifndef EKA2
       
    21 GLDEF_C TInt E32Dll(TDllReason)
       
    22 	{
       
    23 	return KErrNone;
       
    24 	}
       
    25 #endif
       
    26 
       
    27 // server name
       
    28 _LIT(KRedirServerName,"RedirServer");
       
    29 
       
    30 enum TRedirStream 
       
    31 	{
       
    32 	ERedirRead,
       
    33 	ERedirWrite,
       
    34 	ERedirFlush
       
    35 	};
       
    36 
       
    37 // A version must be specified when creating a session with the server
       
    38 const TUint KRedirServMajorVersionNumber=1;
       
    39 const TUint KRedirServMinorVersionNumber=0;
       
    40 const TUint KRedirServBuildVersionNumber=0;
       
    41 
       
    42 
       
    43 //**********************************
       
    44 // CRedirSession
       
    45 //**********************************
       
    46 // This class represents a session in the server.
       
    47 // Functions are provided to respond appropriately to client messages.
       
    48 NONSHARABLE_CLASS(CRedirSession) : public CSession2
       
    49 	{
       
    50 public:
       
    51 	static CRedirSession* NewL(CStreamBase2* aStream);
       
    52 	//service request
       
    53 	virtual void ServiceL(const RMessage2 &aMessage);
       
    54 private :
       
    55 	// construct/destruct
       
    56 	CRedirSession(CStreamBase2* aStream);
       
    57 	~CRedirSession();
       
    58 	//services available to handle read/write requests
       
    59 	TInt WriteStreamL(const RMessage2& aMessage);
       
    60 private:
       
    61 	CStreamBase2* iStream;
       
    62 	};
       
    63 
       
    64 // ------------------- CRedirServer2 implementation --------------------------
       
    65 
       
    66 
       
    67 /**
       
    68 Constructs and allocates memory for a new CRedirServer2 object.
       
    69 @return RedirServer
       
    70 @param aStreamFactory Stream factory.
       
    71 */ 
       
    72 EXPORT_C CRedirServer2* CRedirServer2::NewL(CStreamFactoryBase2* aStreamFactory)
       
    73 	{
       
    74 	CRedirServer2* r=new(ELeave) CRedirServer2(aStreamFactory);
       
    75 	CleanupStack::PushL(r);
       
    76 	r->StartL(KRedirServerName);
       
    77 	CleanupStack::Pop();
       
    78 	return r;
       
    79 	}
       
    80 
       
    81 /**
       
    82 Default constructor
       
    83 @param aStreamFactory Stream factory.
       
    84 */ 
       
    85 CRedirServer2::CRedirServer2(CStreamFactoryBase2* aStreamFactory)
       
    86 	: CServer2(EPriority)
       
    87 	{
       
    88 	iStreamFactory = aStreamFactory;
       
    89 	}
       
    90 
       
    91 /**
       
    92 Virtual destructor
       
    93 */ 	
       
    94 CRedirServer2::~CRedirServer2()
       
    95 	{
       
    96 	}
       
    97 
       
    98 /**
       
    99 Create a new server session. 
       
   100 Checks if the aVersion is the right version and make a new session.
       
   101 @leave KErrNotSupported
       
   102 @return Sharable Session for all threads within a single process.
       
   103 @param aVersion Contains version information.
       
   104 A version is defined by a set of three numbers:major,minor,build version number
       
   105 */
       
   106 CSession2* CRedirServer2::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
       
   107 	{
       
   108 
       
   109 	TVersion v(KRedirServMajorVersionNumber,KRedirServMinorVersionNumber,
       
   110 		KRedirServBuildVersionNumber);
       
   111 	if (!User::QueryVersionSupported(v,aVersion))
       
   112 		User::Leave(KErrNotSupported);
       
   113 	// get a stream object from the current stream factory
       
   114 	CStreamBase2* stream = iStreamFactory->GetStream();
       
   115 	return CRedirSession::NewL(stream);
       
   116 	}
       
   117 
       
   118 /**
       
   119 Sets the stream factory
       
   120 @param aStreamFactory a factory to be set
       
   121 */
       
   122 EXPORT_C void CRedirServer2::SetStreamFactory(CStreamFactoryBase2* aStreamFactory) 
       
   123 	{
       
   124 	// set the stream factory
       
   125 	iStreamFactory = aStreamFactory;
       
   126 	}
       
   127 
       
   128 // ------------------- CRedirSession2 implementation --------------------------
       
   129 CRedirSession* CRedirSession::NewL(CStreamBase2* aStream)
       
   130 	{
       
   131 	return new(ELeave) CRedirSession(aStream);
       
   132 	}
       
   133 
       
   134 CRedirSession::CRedirSession(CStreamBase2* aStream)
       
   135 	: iStream(aStream)
       
   136 	{}
       
   137 
       
   138 CRedirSession::~CRedirSession()
       
   139 	{
       
   140 	// The stream returned by GetStream() is effectively a singleton as 
       
   141 	// implemented in the current redirector, so we leave deletion to
       
   142 	// the factory
       
   143 	}
       
   144 
       
   145 void CRedirSession::ServiceL(const RMessage2& aMessage)
       
   146 	{
       
   147 	TInt ret = KErrNone;
       
   148 	switch (aMessage.Function())
       
   149 		{
       
   150 	case ERedirRead:
       
   151 		// call the Stream to do the read for us
       
   152 		iStream->Read(aMessage);
       
   153 		break;
       
   154 	case ERedirWrite:
       
   155 		TRAP(ret,WriteStreamL(aMessage));
       
   156 		aMessage.Complete(ret);
       
   157 		break;
       
   158 	case ERedirFlush:
       
   159 		// TO DO: ignore flushing?
       
   160 		aMessage.Complete(ret);
       
   161 		break;
       
   162 	default:
       
   163 		aMessage.Complete(KErrNotSupported);
       
   164 		break;
       
   165 		}
       
   166 	return;
       
   167 	}
       
   168 
       
   169 TInt CRedirSession::WriteStreamL(const RMessage2& aMessage)
       
   170 	{
       
   171 	const TInt KMaxTransfer=256;
       
   172 	//
       
   173 	// retrieve the length of the buffer the client wants to write
       
   174 	TInt length = aMessage.Int1();
       
   175 	// retrieve the descriptor to be written
       
   176 	TBuf8<KMaxTransfer> bufDes;
       
   177 	for (TInt offset=0;offset<length;offset+=KMaxTransfer)
       
   178 		{
       
   179 		aMessage.ReadL(0, bufDes, offset);
       
   180 		// send descriptor to stream for printing
       
   181 		iStream->Write(bufDes);
       
   182 		}
       
   183 	return KErrNone;
       
   184 	}
       
   185 
       
   186 // -------------- CLIENT IMPLEMENTATION -----------------------------
       
   187 
       
   188 EXPORT_C TInt RRedirSession2::Connect()
       
   189 	{
       
   190 	TVersion version(KRedirServMajorVersionNumber,KRedirServMinorVersionNumber,
       
   191 		KRedirServBuildVersionNumber);
       
   192 	return CreateSession(KRedirServerName,version,1);	// only one message allowed - no concurrency
       
   193 	}
       
   194 
       
   195 TInt RRedirSession2::CheckEOF(TRequestStatus& aStatus)
       
   196 	{
       
   197 	if (Handle()!=0)
       
   198 		return KErrNone;
       
   199 	TRequestStatus* aStatusPtr=&aStatus;
       
   200 	User::RequestComplete(aStatusPtr,KErrEof);
       
   201 	return KErrEof;
       
   202 	}
       
   203 	
       
   204 EXPORT_C void RRedirSession2::Read(TRequestStatus& aStatus, TDes8& aDes)
       
   205 	{
       
   206 	Read(aStatus, aDes, aDes.MaxLength());
       
   207 	}
       
   208 
       
   209 EXPORT_C void RRedirSession2::Read(TRequestStatus& aStatus, TDes8& aDes, TInt aLength)
       
   210 	{
       
   211 	if (CheckEOF(aStatus))
       
   212 		return;
       
   213 	SendReceive(ERedirRead,TIpcArgs(&aDes,aLength),aStatus);
       
   214 	}
       
   215 
       
   216 EXPORT_C void RRedirSession2::Write(TRequestStatus& aStatus, const TDesC8& aDes)
       
   217 	{
       
   218 	Write(aStatus, aDes, aDes.Length());
       
   219 	}
       
   220 
       
   221 EXPORT_C void RRedirSession2::Write(TRequestStatus& aStatus, const TDesC8& aDes, TInt aLength)
       
   222 //
       
   223 // Write aLength bytes
       
   224 //
       
   225 	{
       
   226 	if (CheckEOF(aStatus))
       
   227 		return;
       
   228 	SendReceive(ERedirWrite,TIpcArgs(&aDes,aLength),aStatus);
       
   229 	}
       
   230 
       
   231 EXPORT_C void RRedirSession2::Flush(TRequestStatus& aStatus)
       
   232 //
       
   233 // Flush output
       
   234 //
       
   235 	{
       
   236 	if (CheckEOF(aStatus))
       
   237 		return;
       
   238 	SendReceive(ERedirFlush,aStatus);
       
   239 	}
       
   240 
       
   241 
       
   242