processstream.monkey2 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. Namespace std.process
  2. #If __TARGET__<>"emscripten"
  3. #rem monkeydoc The ProcessStream class.
  4. #end
  5. Class ProcessStream Extends Stream
  6. #rem monkeydoc The underlying process.
  7. #end
  8. Property Process:Process()
  9. Return _process
  10. End
  11. #rem monkeydoc True if process has ended.
  12. #end
  13. Property Eof:Bool() Override
  14. Return _finished And _stdoutFinished
  15. End
  16. #rem monkeydoc Always 0.
  17. #end
  18. Property Position:Int() Override
  19. Return 0
  20. End
  21. #rem monkeydoc Always -1.
  22. #end
  23. Property Length:Int() Override
  24. Return -1
  25. End
  26. #rem monkeydoc No operation.
  27. #end
  28. Method Seek( position:Int ) Override
  29. End
  30. #rem monkeydoc Reads data from process stdout.
  31. Reads at most `count` bytes from the process.
  32. Returns 0 if the process has ended.
  33. Can return less than `count`, in which case you may have to read again if you know there's more data coming.
  34. @param buf The memory buffer to read data into.
  35. @param count The number of bytes to read from the process.
  36. @return The number of bytes actually read.
  37. #end
  38. Method Read:Int( buf:Void Ptr,count:Int ) Override
  39. Local avail:=_process.StdoutAvail
  40. If Not avail
  41. If _stdoutFinished Return 0
  42. _stdoutWaiting=New Future<Int>
  43. avail=_stdoutWaiting.Get()
  44. _stdoutWaiting=Null
  45. If Not avail Return 0
  46. Endif
  47. Local n:=Min( avail,count )
  48. _process.ReadStdout( buf,n )
  49. Return n
  50. End
  51. #rem monkeydoc Writes data to process stdin.
  52. Writes `count` bytes to the process.
  53. Returns the number of bytes actually written.
  54. Can return less than `count` if the process has ended.
  55. @param buf The memory buffer to read data from.
  56. @param count The number of bytes to write to the process.
  57. @return The number of bytes actually written.
  58. #end
  59. Method Write:Int( buf:Void Ptr,count:Int ) Override
  60. Return _process.WriteStdin( buf,count )
  61. End
  62. #rem monkeydoc Opens a process stream.
  63. Returns null if process stream could not be opened.
  64. @return Null if process stream could not be opened.
  65. #end
  66. Function Open:ProcessStream( cmd:String,mode:String )
  67. Local stream:=New ProcessStream( cmd )
  68. If Not stream.Process Return Null
  69. Return stream
  70. End
  71. Protected
  72. #rem monkeydoc @hidden
  73. #end
  74. Method OnClose() Override
  75. ' _process.Terminate()
  76. End
  77. Private
  78. Field _process:Process
  79. Field _finished:Bool
  80. Field _stdoutFinished:Bool
  81. Field _stdoutWaiting:Future<Int>
  82. Method New( cmd:String )
  83. _process=New Process
  84. _process.Finished+=Lambda()
  85. _finished=True
  86. End
  87. _process.StdoutReady+=Lambda()
  88. Local avail:=_process.StdoutAvail
  89. If Not avail _stdoutFinished=True
  90. If _stdoutWaiting _stdoutWaiting.Set( avail )
  91. End
  92. If _process.Start( cmd ) Return
  93. Print "Failed to start process: "+cmd
  94. _process=Null
  95. End
  96. End
  97. #Endif