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

📄 posix-bin-prim-io.sml

📁 这是我们参加06年全国开源软件的竞赛作品
💻 SML
字号:
(* posix-bin-prim-io.sml * * COPYRIGHT (c) 1995 AT&T Bell Laboratories. * * This implements the UNIX version of the OS specific binary primitive * IO structure.  The Text IO version is implemented by a trivial translation * of these operations (see posix-text-prim-io.sml). *)structure PosixBinPrimIO : OS_PRIM_IO =   struct    structure SV = SyncVar    structure PrimIO = BinPrimIO    structure Vec = Word8Vector    structure PF = Posix.FileSys    structure PIO = Posix.IO    type file_desc = PF.file_desc    val toFPI = Position.fromInt    val bufferSzB = 4096    fun isRegFile fd = PF.ST.isReg(PF.fstat fd)    fun posFns (closed, fd) = if (isRegFile fd)	  then let	    val pos = ref(Position.fromInt 0)	    fun getPos () = !pos	    fun setPos p = (		  if !closed then raise IO.ClosedStream else ();		  pos := PIO.lseek(fd,p,PIO.SEEK_SET))	    fun endPos () = (		  if !closed then raise IO.ClosedStream else ();		  PF.ST.size(PF.fstat fd))	    fun verifyPos () = let		  val curPos = PIO.lseek(fd, Position.fromInt 0, PIO.SEEK_CUR)		  in		    pos := curPos; curPos		  end	    in	      ignore (verifyPos());	      { pos = pos,		getPos = SOME getPos,		setPos = SOME setPos,		endPos = SOME endPos,		verifyPos = SOME verifyPos	      }	    end	  else {	      pos = ref(Position.fromInt 0),	      getPos = NONE, setPos = NONE, endPos = NONE, verifyPos = NONE	    }    fun mkReader {fd, name} = let	  val iod = PF.fdToIOD fd	  val lockMV = SV.mVarInit()	  fun withLock f x = (		SV.mTake lockMV;		(Syscall.doSyscall f x) before SV.mPut(lockMV, ()))		  handle ex => (SV.mPut(lockMV, ()); raise ex)	  fun withLock' NONE = NONE	    | withLock' (SOME f) = SOME(withLock f)	  val closed = ref false          val {pos, getPos, setPos, endPos, verifyPos} = posFns (closed, fd)	  fun incPos k = pos := Position.+(!pos, toFPI k)	  fun blockWrap f x = (		if !closed then raise IO.ClosedStream else ();		f x)	  val readEvt =		IOManager.ioEvt(OS.IO.pollIn(Option.valOf(OS.IO.pollDesc iod)))	  fun eventWrap f x = CML.withNack (fn nack => (		if !closed then raise IO.ClosedStream else ();		case (SV.mTakePoll lockMV)		 of NONE => let		      val replV = SV.iVar()		      in			CML.spawn(fn () => CML.select [			    CML.wrap (readEvt, fn _ => SV.iPut(replV, ())),			    nack			  ]);			CML.wrap(SV.iGetEvt replV, fn _ => f x)		      end		  | (SOME _) => CML.wrap (readEvt,			fn _ => (SV.mPut(lockMV, ()); f x))		(* end case *)))	  fun readVec n = let		val _ = CML.sync readEvt		val v = PIO.readVec(fd, n)		in		  incPos (Vec.length v); v		end	  fun readArr arg = let		val _ = CML.sync readEvt		val k = PIO.readArr(fd, arg)		in		  incPos k; k		end	  fun close () = if !closed		then ()		else (closed:=true; PIO.close fd)	  val isReg = isRegFile fd	  fun avail () = if !closed		  then SOME 0		else if isReg		  then SOME(Position.-(PF.ST.size(PF.fstat fd), !pos))		  else NONE	  in	    BinPrimIO.RD{		name		= name,		chunkSize	= bufferSzB,		readVec		= withLock (blockWrap readVec),		readArr		= withLock (blockWrap readArr),		readVecEvt	= eventWrap readVec,		readArrEvt	= eventWrap readArr,		avail		= withLock avail,		getPos		= withLock' getPos,		setPos		= withLock' setPos,		endPos		= withLock' endPos,		verifyPos	= withLock' verifyPos,		close		= withLock close,		ioDesc		= SOME iod	      }	  end	         fun openRd name = mkReader{	    fd = PF.openf(name, PIO.O_RDONLY, PF.O.flags[]),	    name = name	  }    fun mkWriter {fd, name, appendMode, chunkSize} = let	  val iod = PF.fdToIOD fd	  val lockMV = SV.mVarInit()	  fun withLock f x = (		SV.mTake lockMV;		(Syscall.doSyscall f x) before SV.mPut(lockMV, ()))		  handle ex => (SV.mPut(lockMV, ()); raise ex)	  fun withLock' NONE = NONE	    | withLock' (SOME f) = SOME(withLock f)	  val closed = ref false	  val appendFS = PIO.O.flags(if appendMode then [PIO.O.append] else [])	  fun updateStatus() = PIO.setfl(fd, appendFS)	  fun ensureOpen () = if !closed then raise IO.ClosedStream else ()	  fun putV x = PIO.writeVec x	  fun putA x = PIO.writeArr x	  fun write put arg = (ensureOpen(); put(fd, arg))	  val writeEvt =		IOManager.ioEvt(OS.IO.pollOut(Option.valOf(OS.IO.pollDesc iod)))	  fun eventWrap f x = CML.withNack (fn nack => (		if !closed then raise IO.ClosedStream else ();		case (SV.mTakePoll lockMV)		 of NONE => let		      val replV = SV.iVar()		      in			CML.spawn(fn () => CML.select [			    CML.wrap (writeEvt, fn _ => SV.iPut(replV, ())),			    nack			  ]);			CML.wrap(SV.iGetEvt replV, fn _ => f x)		      end		  | (SOME _) => CML.wrap (writeEvt,			fn _ => (SV.mPut(lockMV, ()); f x))		(* end case *)))	  fun close () = if !closed		then ()		else (closed:=true; PIO.close fd)          val {pos, getPos, setPos, endPos, verifyPos} = posFns (closed, fd)	  in	    BinPrimIO.WR{		name		= name,		chunkSize	= chunkSize,		writeVec	= withLock (write putV),		writeArr	= withLock (write putA),		writeVecEvt	= eventWrap (write putV),		writeArrEvt	= eventWrap (write putA),		getPos		= withLock' getPos,		setPos		= withLock' setPos,		endPos		= withLock' endPos,		verifyPos	= withLock' verifyPos,		close		= withLock close,		ioDesc		= SOME iod	      }	  end    val standardMode = PF.S.flags[	(* mode 0666 *)	    PF.S.irusr, PF.S.iwusr,	    PF.S.irgrp, PF.S.iwgrp,	    PF.S.iroth, PF.S.iwoth	  ]    fun createFile (name, mode, flags) =	  PF.createf(name, mode, flags, standardMode)    fun openWr name = mkWriter{	    fd=createFile(name, PIO.O_WRONLY, PF.O.trunc),	    name=name,	    appendMode=false,	    chunkSize=bufferSzB	  }    fun openApp name = mkWriter{	    fd		= createFile(name, PIO.O_WRONLY, PF.O.append),	    name	= name,	    appendMode	= true,	    chunkSize	= bufferSzB	  }  end; (* PosixBinPrimIO *)

⌨️ 快捷键说明

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