Selaa lähdekoodia

runtime detection for utf8 file system

Nicolas Cannasse 9 vuotta sitten
vanhempi
commit
35dd186d67

+ 30 - 15
std/hl/_std/Sys.hx

@@ -9,9 +9,22 @@ class SysError {
 }
 
 @:coreApi
+@:keepInit
 @:access(String)
 class Sys {
 
+	static var utf8Path : Bool;
+	static function __init__() : Void {
+		utf8Path = sys_utf8_path();
+	}
+	static function getPath( s : String ) : hl.types.Bytes {
+		var size = 0;
+		return utf8Path ? s.bytes.utf16ToUtf8(0, size) : s.bytes;
+	}
+	static function makePath( b : hl.types.Bytes ) : String {
+		return utf8Path ? String.fromUTF8(b) : String.fromUCS2(b);
+	}
+
 	public static function print( v : Dynamic ) : Void {
 		_print(Std.string(v).bytes);
 	}
@@ -48,6 +61,16 @@ class Sys {
 		put_env(s.bytes,if( v == null ) null else v.bytes);
 	}
 
+	public static function environment() : Map<String,String> {
+		var env = sys_env();
+		var h = new haxe.ds.StringMap();
+		for( i in 0...env.length >> 1 ) {
+			var p = i << 1;
+			h.set(String.fromUCS2(env[p]), String.fromUCS2(env[p + 1]));
+		}
+		return h;
+	}
+
 	@:hlNative("std","sys_sleep")
 	public static function sleep( seconds : Float ) : Void {
 	}
@@ -57,11 +80,11 @@ class Sys {
 	}
 
 	public static function getCwd() : String {
-		return String.fromUCS2(get_cwd());
+		return makePath(get_cwd());
 	}
 
 	public static function setCwd( s : String ) : Void {
-		if( !set_cwd(s.bytes) ) throw new SysError("Failed to set path to " + s);
+		if( !set_cwd(getPath(s)) ) throw new SysError("Failed to set path to " + s);
 	}
 
 	public static function systemName() : String {
@@ -72,7 +95,7 @@ class Sys {
 		var code = 0;
 		var ok;
 		if (args == null) {
-			ok = sys_command(cmd.bytes, code);
+			ok = sys_command(getPath(cmd), code);
 		} else {
 			switch (systemName()) {
 				case "Windows":
@@ -80,10 +103,10 @@ class Sys {
 						for (a in [StringTools.replace(cmd, "/", "\\")].concat(args))
 						StringTools.quoteWinArg(a, true)
 					].join(" ");
-					ok = sys_command(cmd.bytes, code);
+					ok = sys_command(getPath(cmd), code);
 				case _:
 					cmd = [cmd].concat(args).map(StringTools.quoteUnixArg).join(" ");
-					ok = sys_command(cmd.bytes, code);
+					ok = sys_command(getPath(cmd), code);
 			}
 		}
 		if( !ok ) throw new SysError("Failed to run command " + cmd);
@@ -91,18 +114,10 @@ class Sys {
 	}
 
 	public static function executablePath() : String {
-		return String.fromUCS2(sys_exe_path());
+		return makePath(sys_exe_path());
 	}
 
-	public static function environment() : Map<String,String> {
-		var env = sys_env();
-		var h = new haxe.ds.StringMap();
-		for( i in 0...env.length >> 1 ) {
-			var p = i << 1;
-			h.set(String.fromUCS2(env[p]), String.fromUCS2(env[p + 1]));
-		}
-		return h;
-	}
+	@:hlNative("std", "sys_utf8_path") static function sys_utf8_path() : Bool { return false; }
 
 	@:hlNative("std","sys_time") public static function time() : Float { return 0.; };
 	@:hlNative("std","sys_exit") public static function exit( code : Int ) : Void {};

+ 13 - 13
std/hl/_std/sys/FileSystem.hx

@@ -22,19 +22,19 @@
 package sys;
 
 @:coreApi
-@:access(String)
+@:access(Sys)
 class FileSystem {
 
 	public static function exists( path : String ) : Bool {
-		return sys_exists(makeCompatiblePath(path).bytes);
+		return sys_exists( Sys.getPath(makeCompatiblePath(path)) );
 	}
 
 	public static function rename( path : String, newPath : String ) : Void {
-		if( !sys_rename(path.bytes, newPath.bytes) ) throw new Sys.SysError("Failed to rename " + path + " to " + newPath);
+		if( !sys_rename( Sys.getPath(path), Sys.getPath(newPath) ) ) throw new Sys.SysError("Failed to rename " + path + " to " + newPath);
 	}
 
 	public static function stat( path : String ) : FileStat {
-		var values = sys_stat(makeCompatiblePath(path).bytes);
+		var values = sys_stat( Sys.getPath(makeCompatiblePath(path)) );
 		if( values == null ) throw new Sys.SysError("Failed to stat " + path);
 		return {
 			gid : values[0],
@@ -52,7 +52,7 @@ class FileSystem {
 	}
 
 	public static function fullPath( relPath : String ) : String {
-		return String.fromUCS2(file_full_path(relPath.bytes));
+		return Sys.makePath( sys_full_path(Sys.getPath(relPath)) );
 	}
 
 	public static function absolutePath ( relPath : String ) : String {
@@ -61,7 +61,7 @@ class FileSystem {
 	}
 
 	public static function isDirectory( path : String ) : Bool {
-		return sys_is_dir(makeCompatiblePath(path).bytes);
+		return sys_is_dir(Sys.getPath(makeCompatiblePath(path)));
 	}
 
 	public static function createDirectory( path : String ) : Void {
@@ -74,24 +74,24 @@ class FileSystem {
 		}
 		for (part in parts) {
 			if (part.charCodeAt(part.length - 1) != ":".code && !exists(part))
-				if( !sys_create_dir(part.bytes, 493) )
+				if( !sys_create_dir(Sys.getPath(part), 493) )
 					throw new Sys.SysError("Failed to create directory " + part);
 		}
 	}
 
 	public static function deleteFile( path : String ) : Void {
-		if( !file_delete(path.bytes) ) throw new Sys.SysError("Can't delete file " + path);
+		if( !sys_delete(Sys.getPath(path)) ) throw new Sys.SysError("Can't delete file " + path);
 	}
 
 	public static function deleteDirectory( path : String ) : Void {
-		if( !sys_remove_dir(path.bytes) ) throw new Sys.SysError("Can't delete directory " + path);
+		if( !sys_remove_dir(Sys.getPath(path)) ) throw new Sys.SysError("Can't delete directory " + path);
 	}
 
 	public static function readDirectory( path : String ) : Array<String> {
-		var content = sys_read_dir(path.bytes);
+		var content = sys_read_dir(Sys.getPath(path));
 		if( content == null )
 			throw new Sys.SysError("Failed to read directory " + path);
-		return [for( c in content ) String.fromUCS2(c)];
+		return [for( c in content ) Sys.makePath(c)];
 	}
 
 	private static inline function makeCompatiblePath(path:String):String {
@@ -107,8 +107,8 @@ class FileSystem {
 	@:hlNative("std", "sys_is_dir") static function sys_is_dir( path : hl.types.Bytes ) : Bool { return false; }
 	@:hlNative("std", "sys_stat") static function sys_stat( path : hl.types.Bytes ) : hl.types.NativeArray<Int> { return null; }
 	@:hlNative("std", "sys_rename") static function sys_rename( path : hl.types.Bytes, to : hl.types.Bytes ) : Bool { return true; }
-	@:hlNative("std", "file_delete") static function file_delete( path : hl.types.Bytes ) : Bool { return true; };
-	@:hlNative("std", "file_full_path") static function file_full_path( path : hl.types.Bytes ) : hl.types.Bytes { return null; }
+	@:hlNative("std", "sys_delete") static function sys_delete( path : hl.types.Bytes ) : Bool { return true; };
+	@:hlNative("std", "sys_full_path") static function sys_full_path( path : hl.types.Bytes ) : hl.types.Bytes { return null; }
 	@:hlNative("std", "sys_remove_dir") static function sys_remove_dir( path : hl.types.Bytes ) : Bool { return true; }
 	@:hlNative("std", "sys_exists") static function sys_exists( path : hl.types.Bytes ) : Bool { return true; }
 

+ 10 - 10
std/hl/_std/sys/io/File.hx

@@ -23,21 +23,21 @@ package sys.io;
 
 typedef FileHandle = hl.types.NativeAbstract<"hl_fdesc">;
 
-@:access(String)
+@:access(Sys)
 @:coreApi class File {
 
 	public static function getContent( path : String ) : String {
 		var size = 0;
-		var bytes = file_contents(path.bytes, size);
+		var bytes = file_contents(Sys.getPath(path), size);
 		if( bytes == null ) throw new Sys.SysError("Can't read "+path);
-		return String.fromUTF8(bytes);
+		return @:privateAccess String.fromUTF8(bytes);
 	}
 
 	public static function getBytes( path : String ) : haxe.io.Bytes {
 		var size = 0;
-		var bytes = file_contents(path.bytes, size);
-		if( bytes == null ) throw new Sys.SysError("Can't open "+path);
-		return haxe.io.Bytes.ofData(new haxe.io.BytesData(bytes,size));
+		var bytes = file_contents(Sys.getPath(path), size);
+		if( bytes == null ) throw new Sys.SysError("Can't read "+path);
+		return @:privateAccess new haxe.io.Bytes(bytes, size);
 	}
 
 	public static function saveContent( path : String, content : String ) : Void {
@@ -53,19 +53,19 @@ typedef FileHandle = hl.types.NativeAbstract<"hl_fdesc">;
 	}
 
 	public static function read( path : String, binary : Bool = true ) : FileInput {
-		var f = file_open(path.bytes,(if( binary ) "rb" else "r").bytes);
+		var f = file_open(Sys.getPath(path),0,binary);
 		if( f == null ) throw new Sys.SysError("Can't open "+path);
 		return @:privateAccess new FileInput(f);
 	}
 
 	public static function write( path : String, binary : Bool = true ) : FileOutput {
-		var f = file_open(path.bytes,(if( binary ) "wb" else "w").bytes);
+		var f = file_open(Sys.getPath(path),1,binary);
 		if( f == null ) throw new Sys.SysError("Can't open "+path+" for writing");
 		return @:privateAccess new FileOutput(f);
 	}
 
 	public static function append( path : String, binary : Bool = true ) : FileOutput {
-		var f = file_open(path.bytes,(if( binary ) "ab" else "a").bytes);
+		var f = file_open(Sys.getPath(path),2,binary);
 		if( f == null ) throw new Sys.SysError("Can't open "+path+" for append");
 		return @:privateAccess new FileOutput(f);
 	}
@@ -78,7 +78,7 @@ typedef FileHandle = hl.types.NativeAbstract<"hl_fdesc">;
 		d.close();
 	}
 
-	@:hlNative("std", "file_open") static function file_open( path : hl.types.Bytes, access : hl.types.Bytes ) : FileHandle { return null; }
+	@:hlNative("std", "file_open") static function file_open( path : hl.types.Bytes, mode : Int, binary : Bool ) : FileHandle { return null; }
 	@:hlNative("std", "file_contents") static function file_contents( path : hl.types.Bytes, size : hl.types.Ref<Int> ) : hl.types.Bytes { return null; }
 
 }

+ 8 - 4
std/hl/_std/sys/io/FileInput.hx

@@ -37,8 +37,9 @@ import sys.io.File;
 	}
 
 	public override function readBytes( s : haxe.io.Bytes, p : Int, l : Int ) : Int {
+		if( p < 0 || l < 0 || p + l > s.length ) throw haxe.io.Error.OutsideBounds;
 		var v = file_read(__f, s.getData().b, p, l);
-		if( v < 0 ) throw new haxe.io.Eof();
+		if( v <= 0 ) throw new haxe.io.Eof();
 		return v;
 	}
 
@@ -48,11 +49,14 @@ import sys.io.File;
 	}
 
 	public function seek( p : Int, pos : FileSeek ) : Void {
-		file_seek(__f,p,switch( pos ) { case SeekBegin: 0; case SeekCur: 1; case SeekEnd: 2; });
+		if( !file_seek(__f,p,switch( pos ) { case SeekBegin: 0; case SeekCur: 1; case SeekEnd: 2; }) )
+			throw haxe.io.Error.Custom("seek() failure");
 	}
 
 	public function tell() : Int {
-		return file_tell(__f);
+		var p = file_tell(__f);
+		if( p < 0 )  throw haxe.io.Error.Custom("tell() failure");
+		return p;
 	}
 
 	public function eof() : Bool {
@@ -63,7 +67,7 @@ import sys.io.File;
 	@:hlNative("std", "file_read") static function file_read( f : FileHandle, bytes : hl.types.Bytes, pos : Int, len : Int ) : Int { return 0; }
 	@:hlNative("std", "file_read_char") static function file_read_char( f : FileHandle ) : Int { return 0; }
 	@:hlNative("std", "file_close") static function file_close( f : FileHandle ) : Void { }
-	@:hlNative("std", "file_seek") static function file_seek( f : FileHandle, pos : Int, from : Int ) : Void { }
+	@:hlNative("std", "file_seek") static function file_seek( f : FileHandle, pos : Int, from : Int ) : Bool { return true; }
 	@:hlNative("std", "file_tell") static function file_tell( f : FileHandle ) : Int { return 0; }
 
 }

+ 9 - 5
std/hl/_std/sys/io/FileOutput.hx

@@ -35,13 +35,14 @@ import sys.io.File;
 	}
 
 	public override function writeBytes( s : haxe.io.Bytes, p : Int, l : Int ) : Int {
+		if( p < 0 || l < 0 || p + l > s.length ) throw haxe.io.Error.OutsideBounds;
 		var v = file_write(__f, s.getData().b, p, l);
-		if( v < 0 ) throw new haxe.io.Eof();
+		if( v <= 0 ) throw new haxe.io.Eof();
 		return v;
 	}
 
 	public override function flush() : Void {
-		file_flush(__f);
+		if( !file_flush(__f) ) throw haxe.io.Error.Custom("flush() failure");
 	}
 
 	public override function close() : Void {
@@ -50,14 +51,17 @@ import sys.io.File;
 	}
 
 	public function seek( p : Int, pos : FileSeek ) : Void {
-		@:privateAccess FileInput.file_seek(__f,p,switch( pos ) { case SeekBegin: 0; case SeekCur: 1; case SeekEnd: 2; });
+		if( @:privateAccess !FileInput.file_seek(__f,p,switch( pos ) { case SeekBegin: 0; case SeekCur: 1; case SeekEnd: 2; }) )
+			throw haxe.io.Error.Custom("seek() failure");
 	}
 
 	public function tell() : Int {
-		return @:privateAccess FileInput.file_tell(__f);
+		var p = @:privateAccess FileInput.file_tell(__f);
+		if( p < 0 )  throw haxe.io.Error.Custom("tell() failure");
+		return p;
 	}
 
-	@:hlNative("std","file_flush") static function file_flush( f : FileHandle ) : Void {}
+	@:hlNative("std","file_flush") static function file_flush( f : FileHandle ) : Bool { return true; }
 	@:hlNative("std", "file_write") static function file_write( f : FileHandle, bytes : hl.types.Bytes, pos : Int, len : Int ) : Int { return 0; }
 	@:hlNative("std", "file_write_char") static function file_write_char( f : FileHandle, v : Int ) : Bool { return true; }
 

+ 3 - 2
std/hl/_std/sys/io/Process.hx

@@ -83,6 +83,7 @@ private class Stdout extends haxe.io.Input {
 
 }
 
+@:access(Sys)
 @:coreApi class Process {
 
 	var p : ProcessHandle;
@@ -96,9 +97,9 @@ private class Stdout extends haxe.io.Input {
 			if( args != null ) {
 				aargs = new hl.types.NativeArray<hl.types.Bytes>(args.length);
 				for( i in 0...args.length )
-					aargs[i] = args[i].bytes;
+					aargs[i] = Sys.getPath(args[i]);
 			}
-			p = _run(cmd.bytes, aargs);
+			p = _run(Sys.getPath(cmd), aargs);
 		}
 		if( p == null )
 			throw new Sys.SysError("Process creation failure : "+cmd);