Explorar el Código

[java/cs] sys.io.Process implementation

Caue Waneck hace 13 años
padre
commit
25ad3682f5

+ 1 - 1
gencommon.ml

@@ -3436,7 +3436,7 @@ struct
   (* from this info, it will infer the applied tparams for the function *)
   (* this function is used by CastDetection module *)
   let infer_params gen pos (original_args:((string * bool * t) list * t)) (applied_args:((string * bool * t) list * t)) (params:(string * t) list) impossible_tparam_is_dynamic : tparams =
-    let args_list args = ( List.map (fun (_,_,t) -> t) (fst args) ) @ (if impossible_tparam_is_dynamic then [] else [snd args]) in
+    let args_list args = ( List.map (fun (_,_,t) -> if impossible_tparam_is_dynamic then gen.greal_type t else t) (fst args) ) @ (if impossible_tparam_is_dynamic then [] else [snd args]) in
     let params_tbl = Hashtbl.create (List.length params) in
     
     let pmap_iter2 fn orig_pmap applied_pmap =

+ 7 - 1
std/cs/_std/sys/io/NativeInput.hx

@@ -2,6 +2,7 @@ package sys.io;
 import haxe.Int64;
 import haxe.io.Bytes;
 import haxe.io.Eof;
+import haxe.io.Error;
 import haxe.io.Input;
 
 class NativeInput extends Input
@@ -24,7 +25,12 @@ class NativeInput extends Input
 	
 	override public function readBytes(s:Bytes, pos:Int, len:Int):Int 
 	{
-		return stream.Read(s.getData(), pos, len);
+		if( pos < 0 || len < 0 || pos + len > s.length )
+			throw Error.OutsideBounds;
+		var ret = stream.Read(s.getData(), pos, len);
+		if (ret == 0)
+			throw new Eof();
+		return ret;
 	}
 	
 	override public function close():Void

+ 113 - 0
std/cs/_std/sys/io/Process.hx

@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2005-2007, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package sys.io;
+import haxe.io.BytesInput;
+import system.io.StreamReader;
+import system.io.StreamWriter;
+
+class Process {
+
+	public var stdout(default,null) : haxe.io.Input;
+	public var stderr(default,null) : haxe.io.Input;
+	public var stdin(default, null) : haxe.io.Output;
+	
+	private var native:NativeProcess;
+	
+
+	public function new( cmd : String, args : Array<String> ) : Void
+	{
+		this.native = new NativeProcess();
+		native.StartInfo.FileName = cmd;
+		var buf = new StringBuf();
+		for (arg in args)
+		{
+			buf.add("\"");
+			buf.add(StringTools.replace(arg, "\"", "\\\""));
+			buf.add("\" ");
+		}
+		native.StartInfo.Arguments = buf.toString();
+		native.StartInfo.RedirectStandardError = native.StartInfo.RedirectStandardInput = native.StartInfo.RedirectStandardOutput = true;
+		native.StartInfo.UseShellExecute = false;
+		
+		native.Start();
+		
+		this.stdout = new sys.io.NativeInput(native.StandardOutput.BaseStream);
+		this.stderr = new sys.io.NativeInput(native.StandardError.BaseStream);
+		this.stdin = new sys.io.NativeOutput(native.StandardInput.BaseStream);
+	}
+	
+	public function getPid() : Int
+	{
+		return native.Id;
+	}
+	
+	public function exitCode() : Int
+	{
+		native.WaitForExit();
+		return native.ExitCode;
+	}
+	
+	public function close() : Void
+	{
+		native.Close();
+	}
+	
+	public function kill() : Void
+	{
+		native.Kill();
+	}
+
+}
+
+/*
+FIXME: The actual process class is much more complex than this, so here it is included a very simplified version.
+*/
+@:native('System.Diagnostics.Process') private extern class NativeProcess
+{
+	var ExitCode(default, null):Int;
+	var Id(default, null):Int;
+	var StartInfo(default, null):NativeStartInfo;
+	var StandardError(default, null):StreamReader;
+	var StandardInput(default, null):StreamWriter;
+	var StandardOutput(default, null):StreamReader;
+	
+	function new():Void;
+	function Close():Void;
+	function Kill():Void;
+	function Start():Void;
+	function WaitForExit():Void;
+}
+
+@:native('System.Diagnostics.ProcessStartInfo') private extern class NativeStartInfo
+{
+	var Arguments:String;
+	var FileName:String;
+	var RedirectStandardError:Bool;
+	var RedirectStandardInput:Bool;
+	var RedirectStandardOutput:Bool;
+	var UseShellExecute:Bool;
+	function new(filename:String, args:String):Void;
+	
+}

+ 6 - 0
std/cs/_std/system/io/StreamReader.hx

@@ -0,0 +1,6 @@
+package system.io;
+
+@:native('System.IO.StreamReader') extern class StreamReader 
+{
+	var BaseStream(default, null):system.io.Stream;
+}

+ 6 - 0
std/cs/_std/system/io/StreamWriter.hx

@@ -0,0 +1,6 @@
+package system.io;
+
+@:native('System.IO.StreamWriter') extern class StreamWriter 
+{
+	var BaseStream(default, null):system.io.Stream;
+}

+ 2 - 2
std/haxe/io/Bytes.hx

@@ -81,9 +81,9 @@ class Bytes {
 		b.position = pos;
 		if( len > 0 ) b.writeBytes(src.b,srcpos,len);
 		#elseif java
-		java.lang.System.arraycopy(b, pos, src.b, srcpos, len);
+		java.lang.System.arraycopy(src.b, srcpos, b, pos, len);
 		#elseif cs
-		system.Array.Copy(b, pos, src.b, srcpos, len);
+		system.Array.Copy(src.b, srcpos, b, pos, len);
 		#else
 		var b1 = b;
 		var b2 = src.b;

+ 8 - 0
std/haxe/io/BytesInput.hx

@@ -83,10 +83,18 @@ class BytesInput extends Input {
 			if( len > avail && avail > 0 ) len = avail;
 			try b.readBytes(buf.getData(),pos,len) catch( e : Dynamic ) throw new Eof();
 		#elseif java
+			var avail : Int = this.len;
+			if ( len > avail ) len = avail;
+			if (len == 0)
+				throw new Eof();
 			java.lang.System.arraycopy(this.b, this.pos, buf.getData(), pos, len);
 			this.pos += len;
 			this.len -= len;
 		#elseif cs
+			var avail : Int = this.len;
+			if ( len > avail ) len = avail;
+			if (len == 0)
+				throw new Eof();
 			system.Array.Copy(this.b,this.pos, buf.getData(), pos, len);
 			this.pos += len;
 			this.len -= len;

+ 19 - 5
std/haxe/io/Input.hx

@@ -86,18 +86,26 @@ class Input {
 		#end
 		
 		#if (cs || java)
-		var buf = Bytes.alloc(bufsize);
+		var buf = null;
 		var total = [];
 		var tlen = 0;
+		var pos = 0;
 		try
 		{
 			while (true)
 			{
-				var len = readBytes(buf, 0, bufsize);
+				if (buf == null || pos >= bufsize)
+				{
+					pos = 0;
+					buf = Bytes.alloc(bufsize);
+					total.push(buf);
+				}
+				
+				var len = readBytes(buf, pos, bufsize - pos);
 				tlen += len;
+				pos += len;
 				if (len == 0)
 					throw Error.Blocked;
-				total.push(buf);
 			}
 		} catch (e:Eof) {
 		}
@@ -107,8 +115,11 @@ class Input {
 			for (buf in total)
 			{
 				var len = buf.getData().Length;
+				if (len > tlen)
+					len = tlen;
 				system.Array.Copy(buf.getData(), 0, ret, idx, len);
-				idx += buf.getData().Length;
+				idx += len;
+				tlen -= len;
 			}
 			return Bytes.ofData(ret);
 			#else
@@ -117,8 +128,11 @@ class Input {
 			for (buf in total)
 			{
 				var len = buf.getData().length;
+				if (len > tlen)
+					len = tlen;
 				java.lang.System.arraycopy(buf.getData(), 0, ret, idx, len);
-				idx += buf.getData().length;
+				idx += len;
+				tlen -= len;
 			}
 			return Bytes.ofData(ret);
 			#end

+ 6 - 1
std/java/_std/sys/io/NativeInput.hx

@@ -30,9 +30,10 @@ class NativeInput extends Input
 	
 	override public function readBytes(s:Bytes, pos:Int, len:Int):Int 
 	{
+		var ret = 0;
 		try
 		{
-			return stream.Read(s.getDate(), pos, len);
+			ret = stream.read(s.getData(), pos, len);
 		}
 		
 		catch (e:EOFException) {
@@ -42,6 +43,10 @@ class NativeInput extends Input
 		catch (e:IOException) {
 			throw haxe.io.Error.Custom(e);
 		}
+		
+		if (ret == -1)
+			throw new Eof();
+		return ret;
 	}
 	
 	override public function close():Void

+ 158 - 0
std/java/_std/sys/io/Process.hx

@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2005-2007, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package sys.io;
+import haxe.io.Bytes;
+import haxe.io.BytesInput;
+import haxe.io.Eof;
+import java.io.Exceptions;
+import java.NativeArray;
+
+class Process {
+
+	public var stdout(default,null) : haxe.io.Input;
+	public var stderr(default,null) : haxe.io.Input;
+	public var stdin(default, null) : haxe.io.Output;
+	
+	private var proc:java.lang.Process;
+
+	public function new( cmd : String, args : Array<String> ) : Void
+	{
+		var pargs = new NativeArray(args.length + 1);
+		pargs[0] = cmd;
+		for (i in 0...args.length)
+		{
+			pargs[i + 1] = args[i];
+		}
+		
+		try
+		{
+			proc = new java.lang.ProcessBuilder(pargs).start();
+		}
+		catch (e:Dynamic) { throw e; } //wrapping typed exceptions
+		
+		var p = proc;
+		stderr = new ProcessInput(p.getErrorStream());
+		stdout = new ProcessInput(p.getInputStream());
+		stdin = new sys.io.NativeOutput(p.getOutputStream());
+	}
+	
+	public function getPid() : Int
+	{
+		if (Reflect.hasField(proc, "pid"))
+			return Reflect.field(proc, "pid");
+		return -1;
+	}
+	
+	public function exitCode() : Int
+	{
+		cast(stdout, ProcessInput).bufferContents();
+		cast(stderr, ProcessInput).bufferContents();
+		try
+		{
+			proc.waitFor();
+		}
+		catch (e:Dynamic) { throw e; }
+		return proc.exitValue();
+	}
+	
+	public function close() : Void
+	{
+		proc.destroy();
+	}
+	
+	public function kill() : Void
+	{
+		proc.destroy();
+	}
+
+}
+
+
+private class ProcessInput extends NativeInput
+{
+	private var chained:BytesInput;
+	
+	public function bufferContents():Void
+	{
+		if (chained != null) return;
+		var b = this.readAll();
+		chained = new BytesInput(b);
+	}
+	
+	override public function readByte():Int 
+	{
+		if (chained != null)
+			return chained.readByte();
+		try
+		{
+			return stream.read();
+		} 
+		catch (e:EOFException) {
+			throw new Eof();
+		}
+		
+		catch (e:IOException) {
+			throw haxe.io.Error.Custom(e);
+		}
+	}
+	
+	override public function readBytes(s:Bytes, pos:Int, len:Int):Int 
+	{
+		if (chained != null)
+			return chained.readBytes(s, pos, len);
+		
+		var ret = -1;
+		try
+		{
+			ret = stream.read(s.getData(), pos, len);
+		}
+		
+		catch (e:EOFException) {
+			throw new Eof();
+		}
+		
+		catch (e:IOException) {
+			throw haxe.io.Error.Custom(e);
+		}
+		
+		if (ret == -1)
+			throw new Eof();
+		return ret;
+	}
+	
+	override public function close():Void
+	{
+		if (chained != null)
+			chained.close();
+		try
+		{
+			stream.close();
+		}
+		
+		catch (e:IOException) {
+			throw haxe.io.Error.Custom(e);
+		}
+	}
+}

+ 12 - 0
std/java/lang/Process.hx

@@ -0,0 +1,12 @@
+package java.lang;
+import java.NativeArray;
+
+extern class Process
+{
+	function destroy():Void;
+	function exitValue():Int;
+	function getErrorStream():java.io.InputStream;
+	function getInputStream():java.io.InputStream;
+	function getOutputStream():java.io.OutputStream;
+	function waitFor():Int;
+}

+ 14 - 0
std/java/lang/ProcessBuilder.hx

@@ -0,0 +1,14 @@
+package java.lang;
+import java.NativeArray;
+
+extern class ProcessBuilder
+{
+	function new(command:NativeArray<String>):Void;
+	
+	@:overload(function (dir:java.io.File):ProcessBuilder {})
+	function directory():java.io.File;
+	
+	//function environment //TODO
+	function redirectErrorStream():Bool;
+	function start():Process;
+}