processstream.monkey2 2.7 KB

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