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

📄 iodev.cpp

📁 在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己的开发
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	iUnicodeTextFile=ETrue; // Assume Unicode by default
	if (mode&EFileWrite && mode&EFileStreamText && (TheRuntime()->UserFlags() & KOplStateOutputAsciiTextFiles))
		iUnicodeTextFile=EFalse;
	switch (iMode&FSER_MASK)
		{
		case (FOPEN):
			{
			DoOpenFileL(fs,aFileName,mode);
			break;
			}
		case (FCREATE):
			{
			User::LeaveIfError(iFile.Create(fs,aFileName,mode));
			break;
			}
		case (FREPLACE):
			{
			User::LeaveIfError(iFile.Replace(fs,aFileName,mode));
			break;
			}
		case (FAPPEND):
			{
			DoOpenFileL(fs,aFileName,mode);
			TInt pos=0;
			User::LeaveIfError(iFile.Seek(ESeekEnd,pos));
			break;
			}
		case (FUNIQUE):
			{
			TFileName fileName;
			TParse parse;
			User::LeaveIfError(fs.Parse(aFileName,parse));
			User::LeaveIfError(iFile.Temp(fs,parse.DriveAndPath(),fileName,mode));
			if (fileName.Length()>aFileName.MaxLength())
				{
				iFile.Close();
				User::Leave(KErrBadName);
				}
			aFileName=fileName;
			break;
			}
		default:
			{
			User::Leave(KOplErrInvalidIO);
			break;
			}
		}
	// If we are in text file mode, additional action is needed. If we are WRITING a file
	// and it's non-Unicode we need to dump out 0xFEFF to the start of it to signify it's
	// Unicode not ASCII. If we are trying to READ a non-Unicode file, we must leave
	// with KErrNotSupported since it's not possible to do this at the moment (i.e.
	// the developer can trap for this error and fall back to opening the ASCII text file
	// in binary mode instead).
	if (mode&EFileStreamText)
		{
		if (mode&EFileWrite && iUnicodeTextFile)
			{
			TInt currentPos=0;
			User::LeaveIfError(iFile.Seek(ESeekCurrent,currentPos));
			if (currentPos==0)
				{
				TBuf8<2> buf(2);
				buf[0]=0xFF;
				buf[1]=0xFE;
				iFile.Write(buf);
				}
			}
		else if (!(mode&EFileWrite) && !iUnicodeTextFile)
			{
			iFile.Close();
			User::Leave(KErrNotSupported);
			}
		}
	}

TUint COplIOFile::GetModeL()
	{
	TUint mode=0;
	switch (iMode&FMT_MASK)
		{
	case (FSTREAM):
		mode=EFileStream;
		break;
	case (FSTREAM_TEXT):
		mode=EFileStreamText;
		break;
	default:
		User::Leave(KErrArgument);
		}
	mode|=(iMode&FUPDATE)?EFileWrite:EFileRead;
	mode|=(iMode&FSHARE)?EFileShareReadersOnly:EFileShareExclusive;
	return mode;
	}

void COplIOFile::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+4,(TUint8*)aParam1,aParam2);
		iFile.Read(((TOplIOReadRequest*)aIOStatus)->iPtr8,aIOStatus->Status());
		}
	else if (aFuncNo==FWRITE)
		{
		__LEAVE_IF_UNALIGNED(aParam1,KOplErrBadAlignment); // No statusPtr to RequestComplete against, at this point.
		aIOStatus=new(ELeave) TOplIOPtrRequest(aOplStatusPtr,EActivePriorityWsEvents+4,(TUint8*)aParam1,aParam2);
		// NOTE: 09/03/2002 (PhilS). We now use iBufferToWrite because the asynchronous
		// Write() method may not complete before this function exits. Previously we just
		// used an automatic, but that could potentially be discarded before the write
		// had finished (leading to a 'General Failure' error in OPL).
		TPtr8 ptr(((TOplIOPtrRequest*)aIOStatus)->iPtr8);
		const TInt length=ptr.Length();
		if (iBufferToWrite)
			{
			delete iBufferToWrite;
			iBufferToWrite=NULL;
			}
		if ((!iUnicodeTextFile) && (length))
			{
			// First get the raw 8-bit data which represents a wide string into an actual
			// 16-bit descriptor so it can be converted properly.
			const TInt halfLength=length>>1;
			HBufC* wideBuf=HBufC::NewLC(halfLength);
			wideBuf->Des().Append((TUint16*)(ptr.Ptr()),halfLength);
			// Convert Unicode buffer into ASCII, then write it to the text file.
			iBufferToWrite=COplRuntimeCharConv::ConvertFromUnicodeToNarrowL(*wideBuf);
			CleanupStack::PopAndDestroy(1); // wideBuf
			}
		else
			{
			iBufferToWrite=ptr.AllocL();
			}
		iFile.Write(*iBufferToWrite,aIOStatus->Status());
		}
	else
		{
		aIOStatus=new(ELeave) TOplIORequest(aOplStatusPtr,EActivePriorityWsEvents+4);
		TRequestStatus* statusPtr=&(aIOStatus->Status());
		switch (aFuncNo)
			{
			case (FCLOSE):
				(TheRuntime()->IOCollection()).RemoveObject(iHandle);
				User::RequestComplete(statusPtr,KErrNone);
				break;
			case (FCANCEL):
				User::RequestComplete(statusPtr,KErrNone);
				break;
			case (FFLUSH):
				User::RequestComplete(statusPtr,iFile.Flush());
				break;
			case (FSEEK):
				{
				if (!(iMode&FRANDOM))
					{
					User::RequestComplete(statusPtr,KErrArgument);
					return; // return here as there's been an error
					}
				TSeek seekMode=ESeekStart;
				switch (OplUtil::GetWord(aParam1))
					{
					case (FABS):
						//seekMode=ESeekStart;
						break;
					case (FEND):
						seekMode=ESeekEnd;
						break;
					case (FCUR):
						seekMode=ESeekCurrent;
						break;
					default:
						User::RequestComplete(statusPtr,KErrArgument);
						return; // return here as there's been an error
					}
				TInt pos=OplUtil::GetLong(aParam2);
				User::RequestComplete(statusPtr,iFile.Seek(seekMode,pos));
				OplUtil::PutLong(aParam2,pos);
				break;
				}
			case (FSETEOF):
				User::RequestComplete(statusPtr,iFile.SetSize(OplUtil::GetLong(aParam1))); // eb205: is this really correct?
				break;
			default:
				User::RequestComplete(statusPtr,KErrArgument);
				return; // return here as there's been an error
			}
		}
	}

COplIOFile::~COplIOFile()
	{
	iFile.Close();
	delete iBufferToWrite;
	}

COplIOFileText::COplIOFileText(TInt16 aHandle)
	:COplIOFile(aHandle)
	{
	}

void COplIOFileText::ConstructL(TBuf<256>& aFileName,TInt16 aMode)
	{
	COplIOFile::ConstructL(aFileName,(TInt16)((aMode&~FMT_MASK)|FSTREAM_TEXT)); // open or create as stream-text
	iTextFile.Set(iFile);
	iMode=aMode;
	}

void COplIOFileText::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.
		TOplIOTextReadRequest* request=new(ELeave) TOplIOTextReadRequest(aOplStatusPtr,EActivePriorityWsEvents+4,(TUint8*)aParam1,aParam2);
		aIOStatus=request;
		TRequestStatus* statusPtr=&request->Status();
		TPtr ptr((TText*)request->iPtr8.Ptr(),request->iPtr8.Length(),request->iPtr8.MaxLength());
		User::RequestComplete(statusPtr,iTextFile.Read(ptr));
		request->iPtr8.SetLength(ptr.Length());
		}
	else if (aFuncNo==FWRITE)
		{
		__LEAVE_IF_UNALIGNED(aParam1,KOplErrBadAlignment); // No statusPtr to RequestComplete against, at this point.
		TOplIOPtrRequest* request=new(ELeave) TOplIOPtrRequest(aOplStatusPtr,EActivePriorityWsEvents+4,(TUint8*)aParam1,aParam2);
		aIOStatus=request;
		TRequestStatus* statusPtr=&request->Status();
		const TPtrC ptr((TText*)request->iPtr8.Ptr(),request->iPtr8.Length()); // Text IO takes number of Unicode chars to write, not bytes.
		if (!iUnicodeTextFile)
			{
			// Convert Unicode buffer into ASCII, then write it to the text file.
			// Note that we write to iFile and NOT iTextFile - iTextFile expects
			// a wide buffer on Unicode builds, but all it does is flush it through
			// to an RFile anyway (see COplIOFileText::ConstructL() where this is set)
			HBufC8* buf=COplRuntimeCharConv::ConvertFromUnicodeToNarrowLC(ptr);
			User::RequestComplete(statusPtr,iFile.Write(*buf));
			iTextFile.Set(iFile);
			CleanupStack::PopAndDestroy(); // buf
			}
		else
			{
			User::RequestComplete(statusPtr,iTextFile.Write(ptr));
			}
		}
	else
		{
		aIOStatus=new(ELeave) TOplIORequest(aOplStatusPtr,EActivePriorityWsEvents+4);
		TRequestStatus* statusPtr=&(aIOStatus->Status());
		switch (aFuncNo)
			{
			case (FCLOSE):
				(TheRuntime()->IOCollection()).RemoveObject(iHandle);
				User::RequestComplete(statusPtr,KErrNone);
				break;
			case (FCANCEL):
				User::RequestComplete(statusPtr,KErrNone);
				break;
			case (FFLUSH):
				User::RequestComplete(statusPtr,iFile.Flush());
				break;
			case (FSEEK):
				{
				if (!(iMode&FRANDOM))
					{
					User::RequestComplete(statusPtr,KErrArgument);
					return; // return here as there's been an error
					}
				TSeek seekMode=ESeekStart;
				switch (OplUtil::GetWord(aParam1))
					{
					case (FREWIND):
						//seekMode=ESeekStart;
						break;
					case (FRSENSE):
					case (FRSET):
					default:
						User::RequestComplete(statusPtr,KErrArgument);
						return; // return here as there's been an error
					}
				//TInt pos=OplUtil::GetLong(aParam2);
				User::RequestComplete(statusPtr,iTextFile.Seek(seekMode));
				//OplUtil::PutLong(aParam2,0);
				break;
				}
			case (FSETEOF):
				{
				const TInt error=iFile.SetSize(OplUtil::GetLong(aParam1)); // eb205: is this really correct?
				if (error!=KErrNone)
					{
					User::RequestComplete(statusPtr,error);
					return; // return here as there's been an error
					}
				iTextFile.Set(iFile);
				User::RequestComplete(statusPtr,iTextFile.Seek(ESeekEnd));
				}
				break;
			default:
				User::RequestComplete(statusPtr,KErrArgument);
				return; // return here as there's been an error
			}
		}
	}

//
// Class TOplIOReadRequest
//
TOplIOReadRequest::TOplIOReadRequest(TOplReqStatus* aStatusPtr,TInt aPriority,TAny* aParam1,TAny* aParam2)
	:TOplIOPtrRequest(aStatusPtr,aPriority,aParam1,aParam2)
	{
	iLenPtr=(TUint16*)aParam2;
	}
	
void TOplIOReadRequest::DoParamsUpdate()
	{
	if (OplUtil::GetWord(iLenPtr)!=0 && iPtr8.Length()==0) //end of file reached!?!
		iStatus=KErrEof;
	else
		OplUtil::PutWord(iLenPtr,(TUint16)iPtr8.Length());
	}

//
// Class TOplIOTextReadRequest
//
TOplIOTextReadRequest::TOplIOTextReadRequest(TOplReqStatus* aStatusPtr,TInt aPriority,TAny* aParam1,TAny* aParam2)
	:TOplIOReadRequest(aStatusPtr,aPriority,aParam1,aParam2)
	{
	}

void TOplIOTextReadRequest::DoParamsUpdate()
	{
	if (iStatus==KErrTooBig)
		iStatus=KOplErrRecord; // OPL1993 also positioned to the start of the next record
	OplUtil::PutWord(iLenPtr,(TUint16)iPtr8.Length());
	}

//
// Class TOplIOPtrRequest
//
TOplIOPtrRequest::TOplIOPtrRequest(TOplReqStatus* aStatusPtr,TInt aPriority,TAny* aParam1,TAny* aParam2)
	:TOplIORequest(aStatusPtr,aPriority), iPtr8((TUint8*)aParam1,OplUtil::GetWord(aParam2),OplUtil::GetWord(aParam2))
	{
	}
	
//
// Class TOplIOCallBackRequest
//
#pragma warning ( disable: 4310) // cast truncates constant
TOplIOCallBackRequest::TOplIOCallBackRequest(TOplReqStatus* aStatusPtr,TInt aPriority,TCallBack aCallBack)
	:TOplIORequest(aStatusPtr,aPriority)
	{
	OplUtil::PutWord(aStatusPtr,(TInt16)KOplErrFilePending);
	iCallBack=aCallBack;
	}
#pragma warning ( default: 4310)

void TOplIOCallBackRequest::DoParamsUpdate()
	{
	TInt ret=iCallBack.CallBack();
	__ASSERT_ALWAYS(ret!=KRequestPending, User::Panic(KOplrIODEV, 1));
	if (ret)
		iStatus=ret;
	}

//
// Class TEraIOCallBackRequest
//
TEraIOCallBackRequest::TEraIOCallBackRequest(TInt32* aStatusPtr,TInt aPriority,TCallBack aCallBack)
	:TIORequest(aStatusPtr, aPriority)
	{
	OplUtil::PutLong(aStatusPtr,KRequestPending);
	iCallBack=aCallBack;
	}

void TEraIOCallBackRequest::DoHandleCompletion()
	{
	TInt ret=iCallBack.CallBack();
	__ASSERT_ALWAYS(ret!=KRequestPending, User::Panic(KOplrIODEV, 2));
	OplUtil::PutLong(iStatusPtr,((ret)?ret:iStatus.Int()));
	}

⌨️ 快捷键说明

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