Implemented RObjectIx-based memoryaccess APIs.
Upshot is that objinfo now works again on platforms that define FSHELL_NO_DOBJECTIX_SUPPORT.
// rcomm.cpp
//
// Copyright (c) 2007 - 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "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:
// Accenture - Initial contribution
//
#include <fshell/ioutils.h>
#include <c32comm.h>
using namespace IoUtils;
class CCmdRcomm : public CCommandBase
{
public:
static CCommandBase* NewLC();
~CCmdRcomm();
private:
CCmdRcomm();
void ReadL();
void WriteL();
private: // From CCommandBase.
virtual const TDesC& Name() const;
virtual void DoRunL();
virtual void ArgumentsL(RCommandArgumentList& aArguments);
virtual void OptionsL(RCommandOptionList& aOptions);
private:
HBufC* iCsyName;
HBufC* iPortName;
HBufC* iMode;
TCommAccess iCommAccess;
TUint iBufSize;
TBool iRaw;
TBool iVerbose;
RCommServ iCommServ;
RComm iComm;
};
CCommandBase* CCmdRcomm::NewLC()
{
CCmdRcomm* self = new(ELeave) CCmdRcomm();
CleanupStack::PushL(self);
self->BaseConstructL();
return self;
}
CCmdRcomm::~CCmdRcomm()
{
delete iCsyName;
delete iPortName;
delete iMode;
iComm.Close();
iCommServ.Close();
}
CCmdRcomm::CCmdRcomm()
: iCommAccess(ECommShared), iBufSize(1024)
{
}
const TDesC& CCmdRcomm::Name() const
{
_LIT(KName, "rcomm");
return KName;
}
void CCmdRcomm::DoRunL()
{
User::LeaveIfError(iCommServ.Connect());
if (iCsyName)
{
TInt err = iCommServ.LoadCommModule(*iCsyName);
if (err && (err != KErrAlreadyExists))
{
PrintError(err, _L("Unable to load comm module \'%S\'"), iCsyName);
User::Leave(err);
}
}
else
{
TInt numPorts;
User::LeaveIfError(iCommServ.NumPorts(numPorts));
for (TInt i = 0; i < numPorts; ++i)
{
TName moduleName;
TSerialInfo serialInfo;
TInt err = iCommServ.GetPortInfo(i, moduleName, serialInfo);
if (err == KErrNone)
{
Printf(_L("%S:\r\n\tPort name: \'%S\'\r\n\tLow unit: %d\r\n\tHigh unit: %d\r\n\tDescription: %S\r\n\r\n"), &moduleName, &serialInfo.iName, serialInfo.iLowUnit, serialInfo.iHighUnit, &serialInfo.iDescription);
}
else
{
PrintWarning(_L("Couldn't get info for port %d, err=%d"), i, err);
}
}
return;
}
if (iPortName)
{
TInt err = iComm.Open(iCommServ, *iPortName, iCommAccess);
LeaveIfErr(err, _L("Unable to open port \'%S\'"), iPortName);
}
else
{
TSerialInfo serialInfo;
_LIT(KCsy, ".csy");
TPtrC csyName(*iCsyName);
if (csyName.Right(KCsy().Length()).CompareF(KCsy) == 0)
{
// Remove the trailing '.csy' because otherwise C32 won't find the module.
csyName.Set(csyName.Left(csyName.Length() - KCsy().Length()));
}
TInt err = iCommServ.GetPortInfo(csyName, serialInfo);
LeaveIfErr(err, _L("Couldn't get port info for CSY '%S'"), &csyName);
Printf(_L("Port name: \'%S\'\r\nLow unit: %d\r\nHigh unit: %d\r\nDescription: %S\r\n"), &serialInfo.iName, serialInfo.iLowUnit, serialInfo.iHighUnit, &serialInfo.iDescription);
return;
}
_LIT(KModeRead, "read");
_LIT(KModeWrite, "write");
if (iMode)
{
if (*iMode == KModeRead)
{
ReadL();
}
else if (*iMode == KModeWrite)
{
WriteL();
}
else
{
PrintError(KErrArgument, _L("Invalid mode: \'%S\'"), iMode);
}
}
}
void CCmdRcomm::ReadL()
{
if (iRaw)
{
HBufC8* readBuf = HBufC8::NewLC(iBufSize);
TPtr8 readBufPtr(readBuf->Des());
TInt err = KErrNone;
while (err == KErrNone)
{
TRequestStatus status;
iComm.ReadOneOrMore(status, readBufPtr);
User::WaitForRequest(status);
err = status.Int();
if (err == KErrNone)
{
TPtrC writePtr((TUint16*)readBuf->Ptr(), readBuf->Length() / 2);
Write(writePtr);
}
else if (iVerbose)
{
PrintWarning(_L("RComm::ReadOneOrMore failed with %d"), err);
}
}
CleanupStack::PopAndDestroy(readBuf);
}
else
{
HBufC8* readBuf = HBufC8::NewLC(iBufSize);
TPtr8 readBufPtr(readBuf->Des());
HBufC* writeBuf = HBufC::NewLC(iBufSize / 2);
TPtr writeBufPtr(writeBuf->Des());
TInt err = KErrNone;
while (err == KErrNone)
{
TRequestStatus status;
iComm.ReadOneOrMore(status, readBufPtr);
User::WaitForRequest(status);
err = status.Int();
if (err == KErrNone)
{
writeBufPtr.Copy(*readBuf);
Write(*writeBuf);
}
else if (iVerbose)
{
PrintWarning(_L("RComm::ReadOneOrMore failed with %d"), err);
}
}
CleanupStack::PopAndDestroy(2, readBuf);
}
}
void CCmdRcomm::WriteL()
{
RIoConsoleReadHandle& stdin = Stdin();
User::LeaveIfError(stdin.SetReadMode(RIoReadHandle::EOneOrMore));
if (iRaw)
{
HBufC* readBuf = HBufC::NewLC(iBufSize / 2);
TPtr readBufPtr(readBuf->Des());
TInt err = KErrNone;
while (err == KErrNone)
{
err = stdin.Read(readBufPtr);
if (err == KErrNone)
{
TPtrC8 writePtr((TUint8*)readBuf->Ptr(), readBuf->Size());
TRequestStatus status;
iComm.Write(status, writePtr);
User::WaitForRequest(status);
LeaveIfErr(status.Int(), _L("RComm::Write failed with %d"), status.Int());
}
}
CleanupStack::PopAndDestroy(readBuf);
}
else
{
HBufC* readBuf = HBufC::NewLC(iBufSize / 2);
TPtr readBufPtr(readBuf->Des());
HBufC8* writeBuf = HBufC8::NewLC(iBufSize);
TPtr8 writeBufPtr(writeBuf->Des());
TInt err = KErrNone;
while (err == KErrNone)
{
err = stdin.Read(readBufPtr);
if (err == KErrNone)
{
writeBufPtr.Copy(*readBuf);
TRequestStatus status;
iComm.Write(status, *writeBuf);
User::WaitForRequest(status);
LeaveIfErr(status.Int(), _L("RComm::Write failed with %d"), status.Int());
}
}
CleanupStack::PopAndDestroy(2, readBuf);
}
}
void CCmdRcomm::ArgumentsL(RCommandArgumentList& aArguments)
{
_LIT(KArg1, "csy_name");
aArguments.AppendStringL(iCsyName, KArg1);
_LIT(KArg2, "port_name");
aArguments.AppendStringL(iPortName, KArg2);
_LIT(KArg3, "mode");
aArguments.AppendStringL(iMode, KArg3);
}
void CCmdRcomm::OptionsL(RCommandOptionList& aOptions)
{
_LIT(KOption1, "access");
aOptions.AppendUintL((TUint&)iCommAccess, KOption1);
_LIT(KOption2, "buffer");
aOptions.AppendUintL(iBufSize, KOption2);
_LIT(KOption3, "raw");
aOptions.AppendBoolL(iRaw, KOption3);
_LIT(KOption4, "verbose");
aOptions.AppendBoolL(iVerbose, KOption4);
}
EXE_BOILER_PLATE(CCmdRcomm)