⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iodev.cpp

📁 在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己的开发
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// IODEV.CPP
//
// Copyright (c) 1997-2002 Symbian Ltd. All rights reserved.

#include "iodev.h"
#include "iodef.h"
#include "oplutil.h"
#include "serial.h"
#include "module.h"

/* 
 * Arm THUMB requires alignment on the 16bit boundary. 
 */
#if defined(__CW32__)
#define __LEAVE_IF_UNALIGNED(aPtr,aLeaveError)\
	if((TUint32)(aPtr)&1)\
		User::Leave((aLeaveError));
#else // Not CodeWarrior
#define __LEAVE_IF_UNALIGNED(aPtr,aLeaveError)\
	if((TUint16)(aPtr)&1)\
		User::Leave((aLeaveError));
#endif

_LIT(KOplrIODEV,"OplrIODEV");

//
// Class COplIOTimer
//
COplIOTimer::COplIOTimer(TInt16 aHandle)
	:COplIO(aHandle)
	{
	}

void COplIOTimer::ConstructL(TBuf<256>& /*aDevName*/, TInt16 /*aMode*/)
	{
	User::LeaveIfError(iTimer.CreateLocal());
	}

COplIOTimer::~COplIOTimer()
	{
	iTimer.Cancel(); // eb205: is any consumption of signals necessary here?
	iTimer.Close();
	}

void COplIOTimer::RunFunctionL(TInt aFuncNo,TIORequest*& aIOStatus,TOplReqStatus* aOplStatusPtr,TAny* aParam1,TAny* /*aParam2*/)
	// eb205: I've replaced calls to "User::Leave(KOplErrInvalidIO)" with calls
	// to "User::RequestComplete(statusPtr,KErrArgument)"
	{
	aIOStatus=new(ELeave) TOplIORequest(aOplStatusPtr,EActivePriorityWsEvents+3);
	TRequestStatus* statusPtr=&aIOStatus->Status();
	switch (aFuncNo)
		{
		case (FRELATIVE):
			{
			TInt32 time=OplUtil::GetLong(aParam1); // maybe should check range
			iTimer.After(*statusPtr,TTimeIntervalMicroSeconds32(time*100000));
			break;
			}
		case (FABSOLUTE):
			{
			TDateTime date(1970,TMonth(0),0,0,0,0,0);
			TTime time(date);
			TTimeIntervalSeconds secs=(TUint32)OplUtil::GetLong(aParam1);
			iTimer.At(*statusPtr,(time+secs));
			break;
			}
		case (FCLOSE):
			{
			(TheRuntime()->IOCollection()).RemoveObject(iHandle);
			User::RequestComplete(statusPtr,KErrNone);
			break;
			}
		case (FCANCEL):
			{
			iTimer.Cancel();
			User::RequestComplete(statusPtr,KErrNone);
			break;
			}
		default:
			{
			User::RequestComplete(statusPtr,KErrArgument);
			return; // return here as there's been an error
			}
		}
	}

//
// Class COplIOComm
//
_LIT(KCommPortName,"COMM::");
_LIT(KUartCsyName,"ECUART");

COplIOComm::COplIOComm(TInt16 aHandle)
	:COplIO(aHandle)
	{
	}

void COplIOComm::ConstructL(TBuf<256>& aDevName,TInt16 aMode)
	{
	if (aDevName.Length()==5)
		{
		TChar port=aDevName[4];
		port.UpperCase();
		if (port.IsAlpha())
			{
			port-='A'-'0'; // TTY:A is COMM0, TTY:B is COMM1 etc.
			User::LeaveIfError(iSession.Connect());
			User::LeaveIfError(iSession.LoadCommModule(KUartCsyName));
			TBuf<16> commPort=KCommPortName();
			commPort.Append(port);
			User::LeaveIfError(iPort.Open(iSession,commPort,ECommExclusive));
			if (aMode==-1) // then try to set OPL1993 defaults
				{
				TCommConfig cBuf;
				TCommConfigV01 &c=cBuf();
				iPort.Config(cBuf);
				c.iRate=EBps9600;
				c.iDataBits=EData8;
				c.iStopBits=EStop1;
				c.iParity=EParityNone;
				c.iHandshake=KConfigObeyCTS;
				c.iParityError=KConfigParityErrorFail;
				c.iFifo=EFifoDisable;
				c.iTerminatorCount=0;
				c.iXonChar=0x11;
				c.iXoffChar=0x13;
				c.iSIREnable=ESIRDisable;
				User::LeaveIfError(iPort.SetConfig(cBuf));
				}
			return;
			}
		}
	User::Leave(KOplErrInvalidIO);
	}

void COplIOComm::RunFunctionL(TInt aFuncNo,TIORequest*& aIOStatus,TOplReqStatus* aOplStatusPtr, TAny* aParam1, TAny* aParam2)
	// eb205: I've replaced calls to "User::Leave(KOplErrInvalidIO)" with calls
	// to "User::RequestComplete(statusPtr,KErrArgument)"
	{
	if (aFuncNo==FREAD)
		{
		__LEAVE_IF_UNALIGNED(aParam1,KOplErrBadAlignment); // No statusPtr to RequestComplete against, at this point.
		aIOStatus=new(ELeave) TOplIOReadRequest(aOplStatusPtr,EActivePriorityWsEvents+5,(TUint8*)aParam1,aParam2); 
		iPort.Read(aIOStatus->Status(),((TOplIOReadRequest*)aIOStatus)->iPtr8);
		}
	else if (aFuncNo==FWRITE)
		{
		__LEAVE_IF_UNALIGNED(aParam1,KOplErrBadAlignment); // No statusPtr to RequestComplete against, at this point.
		aIOStatus=new(ELeave) TOplIOPtrRequest(aOplStatusPtr,EActivePriorityWsEvents+5,(TUint8*)aParam1,aParam2);
		iPort.Write(aIOStatus->Status(),((TOplIOPtrRequest*)aIOStatus)->iPtr8);
		}
	else
		{
		aIOStatus=new(ELeave) TOplIORequest(aOplStatusPtr,EActivePriorityWsEvents+5);
		TRequestStatus* statusPtr=&aIOStatus->Status();
		switch (aFuncNo)
			{
			case (FCLOSE):
				(TheRuntime()->IOCollection()).RemoveObject(iHandle);
				User::RequestComplete(statusPtr,KErrNone);
				break;
			case (FCANCEL):
				iPort.ReadCancel();
				iPort.WriteCancel();
				iPort.Cancel();
				User::RequestComplete(statusPtr,KErrNone);
				break;
			case (FFLUSH):
				iPort.ResetBuffers();
				User::RequestComplete(statusPtr,KErrNone); // eb205: I've added this
				break;
			case (FSET):
				{
				TCommConfig configBuf;
				TCommConfigV01& config=configBuf();
				iPort.Config(configBuf);
				P_SRCHAR& newConfig=*(P_SRCHAR*)aParam1;
				config.iRate=(TBps)(Max(newConfig.tbaud,newConfig.rbaud)-1);
				config.iDataBits=(TDataBits)(P_DATA_MASK&newConfig.frame);
				config.iStopBits=(newConfig.frame&P_TWOSTOP)?EStop2:EStop1;
				config.iParity=(newConfig.frame&P_PARITY)?((TParity)newConfig.parity):EParityNone;
				config.iHandshake=Handshake(newConfig.hand);
				config.iParityError=(newConfig.flags&P_IGNORE_PARITY)?KConfigParityErrorIgnore:KConfigParityErrorFail;
				config.iXonChar=newConfig.xon;
				config.iXoffChar=newConfig.xoff;
				const TInt returnValue=Terminators(OplUtil::GetLong(&newConfig.tmask),config.iTerminator);
				if (returnValue<0)
					{
					User::RequestComplete(statusPtr,returnValue);
					return; // return here as there's been an error
					}
				config.iTerminatorCount=returnValue;
				User::RequestComplete(statusPtr,iPort.SetConfig(configBuf));
				break;
				}
			case (FSENSE):
				{
				TCommConfig configBuf;
				TCommConfigV01& config=configBuf();
				iPort.Config(configBuf);
				P_SRCHAR& out=*(P_SRCHAR*)aParam1;
				out.tbaud=out.rbaud=(TUint8)((config.iRate==EBpsSpecial)?0:(config.iRate+1)); // EBpsSpecial returned as zero
				out.frame=(TUint8)(config.iDataBits|((config.iStopBits==EStop2)?P_TWOSTOP:0)|((config.iParity==0)?0:P_PARITY));
				out.parity=(TUint8)config.iParity;
				out.hand=Handshake(config.iHandshake);
				out.xon=config.iXonChar;
				out.xoff=config.iXoffChar;
				out.flags=(TUint8)((config.iParityError==KConfigParityErrorIgnore)?P_IGNORE_PARITY:0);
				TUint32 terminatorMask=0;
				for (TInt i=0; i<config.iTerminatorCount; ++i)
					{
					TInt pos=config.iTerminator[i];
					if (pos<0 || pos>31)
						{
						User::RequestComplete(statusPtr,KErrGeneral); // eb205: this was User::Leave(KOplErrInvalidIO)
						return; // return here as there's been an error
						}
					terminatorMask|=(0x1<<pos);
					}
				OplUtil::PutLong(&out.tmask,terminatorMask);
				User::RequestComplete(statusPtr,KErrNone);
				break;
				}
			case (FTEST):
				OplUtil::PutWord((TUint16*)aParam1,(TUint16)iPort.QueryReceiveBuffer());
				User::RequestComplete(statusPtr,KErrNone);
				break;
			case (FINQ):
				{
				TCommCaps capsBuf;
				TCommCapsV01& caps=capsBuf();
				iPort.Caps(capsBuf);
				OplUtil::PutLong(aParam1,(TInt32)caps.iRate);
				TUint flags=caps.iDataBits;
				if (caps.iStopBits&KCapsStop2)
					flags|=P_SRINQ_STOP2;
				flags|=((caps.iParity&~KCapsParityNone)<<4);
				if (caps.iSignals&KCapsSignalDTRSupported)
					flags|=P_SRINQ_SETDTR;
				if ((caps.iHandshake&KCapsObeyXoffSupported) && (caps.iHandshake&KCapsSendXoffSupported))
					flags|=P_SRINQ_XONXOFF;
				OplUtil::PutWord((TUint16*)aParam1+2,(TUint16)flags);
				User::RequestComplete(statusPtr,KErrNone);
				break;
				}
			case (FCTRL):
				{
				TUint signals=iPort.Signals(KSignalCTS|KSignalDSR|KSignalDCD);
				*(TUint8*)aParam1=(TUint8)signals;
				TUint8 setDTR=*((TUint8*)aParam1+1);
				if (setDTR==1)
					iPort.SetSignalsToMark(KSignalDTR);
				else if (setDTR==2)
					iPort.SetSignalsToSpace(KSignalDTR);
				User::RequestComplete(statusPtr,KErrNone);
				break;
				}
			case (FXSET):
				{
				TCommConfig cBuf;
				Mem::Copy(&cBuf(),aParam1,sizeof(TCommConfigV01));
				User::RequestComplete(statusPtr,iPort.SetConfig(cBuf));
				break;
				}
			case (FXSENSE):
				{
				TCommConfig cBuf;
				iPort.Config(cBuf);
				Mem::Copy(aParam1,&cBuf(),sizeof(TCommConfigV01));
				User::RequestComplete(statusPtr,KErrNone);
				break;
				}
			case (FXINQ):
				{
				TCommCaps caps;
				iPort.Caps(caps);
				Mem::Copy(aParam1,&caps(),sizeof(TCommCapsV01));
				User::RequestComplete(statusPtr,KErrNone);
				break;
				}
			case (FXCTRL):
				{
				OplUtil::PutWord((TUint16*)aParam1,(TUint16)iPort.Signals(KSignalCTS|KSignalDSR|KSignalDCD|KSignalRNG|KSignalRTS|KSignalDTR));
				TUint set=OplUtil::GetWord((TUint16*)aParam1+1);
				TUint clear=OplUtil::GetWord((TUint16*)aParam1+2);
				iPort.SetSignalsToMark(set&~clear);
				iPort.SetSignalsToSpace(clear&~set);
				User::RequestComplete(statusPtr,KErrNone);
				break;
				}
			default:
				User::RequestComplete(statusPtr,KErrArgument);
				return; // return here as there's been an error
			}
		}
	}

TUint COplIOComm::Handshake(TUint8 aOpl1993Handshake)
	{
	TUint opler1Handshake;
	if (aOpl1993Handshake&P_IGN_CTS)
		opler1Handshake=0;
	else
		opler1Handshake=KConfigObeyCTS;
	opler1Handshake|=(aOpl1993Handshake&0x3); // Obey/Send Xoff
	return opler1Handshake|((aOpl1993Handshake&0x78)<<1);
	}

TUint8 COplIOComm::Handshake(TUint aOpler1Handshake)
	{
	TUint opl1993Handshake=0;
	if (!(aOpler1Handshake&KConfigObeyCTS))
		opl1993Handshake=P_IGN_CTS;
	opl1993Handshake|=(aOpler1Handshake&0x3);
	return (TUint8)(opl1993Handshake|((aOpler1Handshake>>1)&0x78));
	}

TInt COplIOComm::Terminators(TUint32 aMask,TText8* charPtr)
	{
	TInt count=0;
	for (TInt ii=0;ii<32;ii++)
		{
		if ((aMask>>ii)&0x1)
			{
			count++;
			if (count>KConfigMaxTerminators)
				{
				return KErrNotSupported;
				}
			*charPtr++=(TUint8)ii;
			}
		}
	return count;
	}

COplIOComm::~COplIOComm()
	{
	if (iPort.IsOpen())
		{
		iPort.ReadCancel();
		iPort.WriteCancel();
		iPort.Cancel();
		// eb205: is any consumption of signals necessary here?
		}
	iPort.Close();
	iSession.Close();
	}

//
// Class COplIOFile
//
COplIOFile::COplIOFile(TInt16 aHandle)
	:COplIO(aHandle)
	{
	}

void COplIOFile::DoOpenFileL(RFs& aRFs,TBuf<256>& aFileName,TUint aMode)
	{
	User::LeaveIfError(iFile.Open(aRFs,aFileName,aMode));
	// If we're in text mode, check whether we have opened a Unicode text file or not
	if (aMode&EFileStreamText)
		{
		// Read the first two bytes of the file
		HBufC8* tempBuf=HBufC8::NewLC(2);
		TPtr8 ptr(tempBuf->Des());
		User::LeaveIfError(iFile.Read(ptr,2));
		if (!(ptr[0]==0xFF && ptr[1]==0xFE) && !(ptr[0]==0xFE && ptr[1]==0xFF)) // Not Unicode
			iUnicodeTextFile=EFalse;
		CleanupStack::PopAndDestroy(); //tempBuf
		// Reset the file to the start for any future use
		TInt currentPos=0;
		User::LeaveIfError(iFile.Seek(ESeekStart,currentPos));
		}
	}

void COplIOFile::ConstructL(TBuf<256>& aFileName,TInt16 aMode)
	{
	RFs& fs=TheRuntime()->ConEnv()->FsSession();
	iMode=aMode;
	const TUint mode=GetModeL();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -