[Pkg-cli-apps-commits] [fsharp] 42/60: reimplement async reading from redirected stdout\stderr
Christopher Halse Rogers
raof-guest at moszumanska.debian.org
Sun Sep 14 08:13:41 UTC 2014
This is an automated email from the git hooks/post-receive script.
raof-guest pushed a commit to branch master
in repository fsharp.
commit d29a5e226e881374e9065df2bcc9fcb850a39e91
Author: desco <desco.by at gmail.com>
Date: Sat Aug 23 23:32:48 2014 -0700
reimplement async reading from redirected stdout\stderr
---
.../src/vs/FsPkgs/FSharp.VS.FSI/sessions.fs | 55 ++++++++++++++++++----
1 file changed, 47 insertions(+), 8 deletions(-)
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/sessions.fs b/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/sessions.fs
index 35bab88..d7be909 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/sessions.fs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/sessions.fs
@@ -171,6 +171,48 @@ let determineFsiPath () =
else
raise (SessionError (VFSIstrings.SR.couldNotFindFsiExe fsiRegistryPath))
+let readLinesAsync(reader: System.IO.StreamReader): IEvent<string> =
+ let newLine = Event<_>()
+ let buffer = System.Text.StringBuilder(1024)
+ let byteBuffer = Array.zeroCreate 128
+ let encoding = System.Text.Encoding.UTF8
+ let decoder = encoding.GetDecoder()
+ let async0 = async.Return 0
+ let charBuffer =
+ let maxCharsInBuffer = encoding.GetMaxCharCount byteBuffer.Length
+ Array.zeroCreate maxCharsInBuffer
+
+ let rec findLinesInBuffer pos =
+ if pos >= buffer.Length then max (buffer.Length - 1) 0 // exit and point to the last char
+ else
+ let c = buffer.[pos]
+ if c = '\r' || c = '\n' then
+ let line = buffer.ToString(0, pos)
+ newLine.Trigger line
+
+ let deletePos =
+ if c = '\r' && (pos + 1) < buffer.Length && buffer.[pos + 1] = '\n' then pos + 2 else pos + 1
+ buffer.Remove(0, deletePos) |> ignore
+ findLinesInBuffer 0
+ else
+ findLinesInBuffer (pos + 1)
+
+ let rec read pos =
+ async {
+ let! bytesRead =
+ try
+ reader.BaseStream.AsyncRead(byteBuffer, 0, byteBuffer.Length)
+ with
+ | :? IOException -> async0
+ if bytesRead <> 0 then
+ let charsRead = decoder.GetChars(byteBuffer, 0, bytesRead, charBuffer, 0)
+ buffer.Append(charBuffer, 0, charsRead) |> ignore
+ let newPos = findLinesInBuffer pos
+ return! read newPos
+ }
+ Async.StartImmediate (read 0)
+ newLine.Publish
+
let fsiStartInfo channelName =
let procInfo = new ProcessStartInfo()
let fsiPath = determineFsiPath ()
@@ -208,16 +250,13 @@ let fsiProcess (procInfo:ProcessStartInfo) =
let outW,outE = let e = new Event<_>() in e.Trigger, e.Publish
let errW,errE = let e = new Event<_>() in e.Trigger, e.Publish
let exitE = (cmdProcess.Exited |> Observable.map (fun x -> x)) // this gives the event the F# "standard" event type IEvent<'a> rather than IEvent<_,_>
-
- // wire up output (to both stdout and stderr)
- cmdProcess.OutputDataReceived |> catchAll |> Observable.add(fun data ->
- //System.Windows.Forms.MessageBox.Show (sprintf "OutputDataRecieved '%s'\n" data.Data) |> ignore
- outW(data.Data));
- cmdProcess.ErrorDataReceived |> catchAll |> Observable.add (fun data -> errW(data.Data));
let _ = cmdProcess.Start()
- cmdProcess.BeginOutputReadLine();
- cmdProcess.BeginErrorReadLine();
+ // wire up output (to both stdout and stderr)
+ readLinesAsync cmdProcess.StandardOutput |> catchAll |> Observable.add(fun data ->
+ //System.Windows.Forms.MessageBox.Show (sprintf "OutputDataRecieved '%s'\n" data.Data) |> ignore
+ outW(data));
+ readLinesAsync cmdProcess.StandardError |> catchAll |> Observable.add (fun data -> errW(data));
// wire up input
// Fix 982: Force input to be written in UTF8 regardless of the apparent encoding.
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-cli-apps/packages/fsharp.git
More information about the Pkg-cli-apps-commits
mailing list