Code archives/Miscellaneous/fmc.StdIOStream
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Since 2006-11-06 my modules stored in the code archives are out of synchronization. To have the latest version you need to use the bmk/syncmods utility or the MaxIDE. You need to add "webspace100.we.funpic.de/root/mod" as a new line to "cfg/modservers.cfg" in your BlitzMax installation directory. You can't synchronize with the default BlitzMax 1.22 IDE. If you don't have another IDE, you need to download a tweaked MaxIDE. You need to specify "fmc" as additional module scope. Alternative you can synchronize with the bmk tool: bmk syncmods fmc For a better description see my thread in the programming forum introducing these modules. Needed modules: fmc.IOStream fmc.Development fmc.ObjectTool | |||||
Strict Rem bbdoc:StdIOStream EndRem Module fmc.StdIOStream ModuleInfo "Version: 0.05" ModuleInfo "Modserver: Fabian" Import brl.standardio Import fmc.IOStream Import fmc.Development Import fmc.ObjectTool Rem bbdoc:Get standard input and output stream returns:The standard input and output stream about: This function returns the application's standard input and output stream. You can use this stream to exchange information with the calling application or the user. Note that #brl.standardio.StandardIOStream is set to this stream when the application starts up. You also can get this stream calling #brl.stream.OpenStream with "object::stdio" as parameter. Note that #brl.stream.OpenStream with "object::standardio" as parameter will return #brl.standardio.StandardIOStream. EndRem Function StdIOStream:TStream ( ) Return Stream EndFunction Rem bbdoc:Get the application's command line returns:The application's command line about: This function returns the application's command line. With the optional parameter @RemoveApp you can control whether the function removes the application's name and trims the line before it returns it. EndRem Function CommandLine$ ( RemoveApp = True ) If RemoveApp Return Line1 EndIf Return Line0 EndFunction Private Global Line0$ Global Line1$ MakeCmdLine Global Stream:TStdIOStream = New TStdIOStream StandardIOStream = Stream New TObjectStreamFactory ?Win32 BufferedInput Global InHandle = GetStdHandle ( -10 ) Global OutHandle = GetStdHandle ( -11 ) Global DataEof Function BufferedInput ( ) Global BufferLen = 1024 Global Buffer:Byte Ptr = MemAlloc ( BufferLen ) Global ThreadIn = GetStdHandle ( -10 ) Global ThreadOut Local Pipe CreatePipe Varptr Pipe , Varptr ThreadOut , Null , 0 SetStdHandle -10 , Pipe DebugSuspend UpdateCStream Global T:TThread = TThread.Create ( Thread , 0 ) DebugResume Function Thread ( Context ) Local PipeThreadIn = PeekNamedPipe ( ThreadIn , Null , 0 , Null , Null , Null ) Repeat Local All Local Cur If Not ( ReadFile ( ThreadIn , Buffer , BufferLen , Varptr All , Null ) And ( All Or PipeThreadIn ) ) DataEof = True CloseHandle ThreadOut Return EndIf While All > Cur Local N WriteFile ThreadOut , Buffer + Cur , All - Cur , Varptr N , Null Cur :+ N Wend If All CallbackMain Func , All EndIf Forever EndFunction Function UpdateCStream ( ) ( Int Ptr stdin_ ) [ 4 ] = _open_osfhandle ( GetStdHandle ( -10 ) , $8000 ) ( Int Ptr stdout_ ) [ 4 ] = _open_osfhandle ( GetStdHandle ( -11 ) , $8001 ) ( Int Ptr stderr_ ) [ 4 ] = _open_osfhandle ( GetStdHandle ( -12 ) , $8001 ) Extern Function _open_osfhandle ( osfhandle , access ) EndExtern EndFunction Function Func ( Context ) TEvent.Create ( EVENT_READAVAIL , Stream , Context ).Emit EndFunction EndFunction Extern "Win32" Function GetStdHandle ( N ) Function SetStdHandle ( N , Handle ) Function CreatePipe ( In Ptr , Out Ptr , PA:Byte Ptr , Size ) Function FlushFileBuffers ( File ) Function PeekNamedPipe ( Pipe , Buffer:Byte Ptr , Size , Read Ptr , Avail Ptr , BLTM Ptr ) Function ReadFile ( File , Buffer:Byte Ptr , Size , Read Ptr , O:Byte Ptr ) Function WriteFile ( File , Buffer:Byte Ptr , Size , Written Ptr , O:Byte Ptr ) Function GetCommandLineW:Short Ptr ( ) Function CloseHandle ( Handle ) EndExtern ? Function MakeCmdLine ( ) ?Win32 Line0 = String.FromWString ( GetCommandLineW ( ) ) ?Linux | MacOS For Local AppArg$ = EachIn AppArgs Line0 :+ " ~q" + AppArg + "~q" Next Line0 = Line0 [ 1 ..] ? Line1 = Line0.Trim ( ) If Line1 [.. 1 ] = "~q" Line1 = Line1 [ Line1.Find ( "~q" , 1 ) + 1 ..] Else While Line1 [.. 1 ].Trim ( ) Line1 = Line1 [ 1 ..] Wend EndIf Line1 = Line1.Trim ( ) EndFunction Type TStdIOStream Extends TStream Method Eof ( ) ?Win32 Return DataEof And Not Size ( ) ?Linux | MacOS Return feof_ ( stdin_ ) ? EndMethod Method Pos ( ) Return -1 EndMethod Method Size ( ) ?Win32 Local Avail PeekNamedPipe InHandle , Null , 0 , Null , Varptr Avail , Null Return Avail ? EndMethod Method Seek ( pos ) ?Win32 If pos = -1 Return -3 EndIf ? Return -1 EndMethod Method Flush ( ) ?Win32 FlushFileBuffers OutHandle ?Linux | MacOS fflush_ stdout_ ? EndMethod Method Close ( ) EndMethod Method Read ( buf:Byte Ptr , count ) ?Win32 ReadFile InHandle , buf , count , Varptr count , Null Return count ?Linux | MacOS Return fread_ ( buf , 1 , count , stdin_ ) ? EndMethod Method Write ( buf:Byte Ptr , count ) ?Win32 WriteFile OutHandle , buf , count , Varptr count , Null Return count ?Linux | MacOS Return fwrite_ ( buf , 1 , count , stdout_ ) ? EndMethod EndType Type TObjectStreamFactory Extends TStreamFactory Method CreateStream:TStream ( url:Object , proto$ , path$ , readable , writeable ) Local Array:Object [] = Object [] ( url ) If Array Local U$ Local H [ Len Array ] For Local I = 0 Until Len Array Local T$ = String Array [ I ] If T U :+ T Else H [ I ] = OpenHandle ( Array [ I ] ) U :+ "object::" + H [ I ] EndIf Next Local S:TStream = OpenStream ( U , readable , writeable ) For Local N = EachIn H If N CloseHandle N EndIf Next Return S EndIf If proto = "object" Local I = Int path If I Return OpenStream ( ObjectForHandle ( I ) , readable , writeable ) EndIf If path.ToLower ( ) = "stdio" Return Stream EndIf If path.ToLower ( ) = "standardio" Return StandardIOStream EndIf EndIf EndMethod EndType |
Comments
| ||
Is this different in some way from BRL.StandardIO ? |
| ||
Yes, a bit: * brl.standardio allows you to change the standardio stream object. That means that you can't be sure whether StandardIOStream is really the standard-io-stream. * The brl.standardio stream object is a text stream, so you can't write a single byte to it using WriteByte. * brl.standardio uses a text-type c-stream; that means that incoming bytes with the value 13 are deleted - outcoming bytes with the value 10 are prefixed with bytes with the value 13. * fmc.StdIOStream adds a stdio stream and object stream factory. |
| ||
And, since the last update: * fmc.StdIOStream allows you to get the number of bytes available to read from the standard input stream without causing the application to block. * fmc.StdIOStream provides a function to get the programme's command line unchanged - with whitespace syntax intact. * fmc.StdIOStream emits a read avail event if there's new data to read from the standard input stream. |
Code Archives Forum