ソースを参照

__resolve -> resolve
haxe.io + Bytes working

Nicolas Cannasse 17 年 前
コミット
cffe811ac4

+ 1 - 0
doc/CHANGES.txt

@@ -26,6 +26,7 @@ TODO inlining : substitute class+function type parameters in order to have fully
 	allow up to 8 parameters in Reflect.createInstance
 	flash9 : some minor optimizations in haxe.Serializer
 	added haxe.io package (removed things from neko.io)
+	__resolve becomes resolve (and should be documented)
 	TODO read/write int31+int32
 
 2008-04-05: 1.19

+ 1 - 1
genas3.ml

@@ -740,7 +740,7 @@ let generate_field ctx static f =
 	ctx.in_static <- static;
 	ctx.locals <- PMap.empty;
 	ctx.inv_locals <- PMap.empty;
-	let public = f.cf_public || Hashtbl.mem ctx.get_sets (f.cf_name,static) || (f.cf_name = "main" && static) || f.cf_name = "__resolve" in
+	let public = f.cf_public || Hashtbl.mem ctx.get_sets (f.cf_name,static) || (f.cf_name = "main" && static) || f.cf_name = "resolve" in
 	let rights = (if static then "static " else "") ^ (if public then "public" else "protected") in
 	let p = ctx.curclass.cl_pos in
 	match f.cf_expr with

+ 2 - 2
std/haxe/Stack.hx

@@ -48,7 +48,7 @@ class Stack {
 			a.pop(); // remove Stack.callStack()
 			return a;
 		#elseif flash9
-			return null;
+			return new Array();
 		#elseif (flash || js)
 			return makeStack("$s");
 		#else
@@ -65,7 +65,7 @@ class Stack {
 		#if neko
 			return makeStack(untyped __dollar__excstack());
 		#elseif flash9
-			return null;
+			return new Array();
 		#elseif (flash ||js)
 			return makeStack("$e");
 		#else

+ 25 - 11
std/haxe/io/Bytes.hx

@@ -27,13 +27,7 @@ package haxe.io;
 class Bytes {
 
 	public var length(default,null) : Int;
-	#if neko
-	var b : Void; // neko-string
-	#elseif flash9
-	var b : flash.utils.ByteArray;
-	#else
-	var b : Array<Int>;
-	#end
+	var b : BytesData;
 
 	function new(length,b) {
 		this.length = length;
@@ -62,10 +56,10 @@ class Bytes {
 
 	public function blit( pos : Int, src : Bytes, srcpos : Int, len : Int ) : Void {
 		#if !neko
-		if( pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length ) throw "Outside bounds";
+		if( pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length ) throw Error.OutsideBounds;
 		#end
 		#if neko
-		try untyped __dollar__sblit(b,pos,src.b,srcpos,len) catch( e : Dynamic ) throw "Outside bounds";
+		try untyped __dollar__sblit(b,pos,src.b,srcpos,len) catch( e : Dynamic ) throw Error.OutsideBounds;
 		#elseif flash9
 		b.position = pos;
 		b.writeBytes(src.b,srcpos,len);
@@ -85,6 +79,22 @@ class Bytes {
 		#end
 	}
 
+	public function sub( pos : Int, len : Int ) : Bytes {
+		#if !neko
+		if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
+		#end
+		#if neko
+		return try new Bytes(len,untyped __dollar__ssub(b,pos,len)) catch( e : Dynamic ) throw Error.OutsideBounds;
+		#elseif flash9
+		b.position = pos;
+		var b2 = new flash.utils.ByteArray();
+		b.readBytes(b2,0,len);
+		return new Bytes(len,b2);
+		#else
+		return new Bytes(len,b.slice(pos,pos+len));
+		#end
+	}
+
 	public function compare( other : Bytes ) : Int {
 		#if neko
 		return untyped __dollar__compare(b,other.b);
@@ -117,10 +127,10 @@ class Bytes {
 
 	public function readString( pos : Int, len : Int ) : String {
 		#if !neko
-		if( pos < 0 || len < 0 || pos + len > length ) throw "Outside bounds";
+		if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
 		#end
 		#if neko
-		return try new String(untyped __dollar__ssub(b,pos,len)) catch( e : Dynamic ) throw "Outside bounds";
+		return try new String(untyped __dollar__ssub(b,pos,len)) catch( e : Dynamic ) throw Error.OutsideBounds;
 		#elseif flash9
 		b.position = pos;
 		return b.readUTFBytes(len);
@@ -161,6 +171,10 @@ class Bytes {
 		#end
 	}
 
+	public inline function getData() : BytesData {
+		return b;
+	}
+
 	public static function alloc( length : Int ) : Bytes {
 		#if neko
 		return new Bytes(length,untyped __dollar__smake(length));

+ 6 - 3
std/haxe/io/BytesBuffer.hx

@@ -55,13 +55,16 @@ class BytesBuffer {
 	}
 
 	public inline function addBytes( src : Bytes, pos : Int, len : Int ) {
+		#if !neko
+		if( pos < 0 || len < 0 || pos + len > src.length ) throw Error.OutsideBounds;
+		#end
 		#if neko
-		untyped StringBuf.__add_sub(b,src.b,pos,len);
+		try untyped StringBuf.__add_sub(b,src.getData(),pos,len) catch( e : Dynamic ) throw Error.OutsideBounds;
 		#elseif flash9
-		b.writeBytes(untyped src.b,pos,len);
+		b.writeBytes(src.getData(),pos,len);
 		#else
 		var b1 = b;
-		var b2 = untyped src.b;
+		var b2 = src.getData();
 		for( i in pos...pos+len )
 			b.push(b2[i]);
 		#end

+ 33 - 0
std/haxe/io/BytesData.hx

@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2005-2008, 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 haxe.io;
+
+#if neko
+	typedef BytesData =	Void; // neko-string
+#elseif flash9
+	typedef BytesData =	flash.utils.ByteArray;
+#else
+	typedef BytesData = Array<Int>;
+#end

+ 68 - 27
std/haxe/io/BytesInput.hx

@@ -26,47 +26,88 @@ package haxe.io;
 
 class BytesInput extends Input {
 
-	#if neko
-	var b : Void; // neko string
-	#else flash9
-	var b : flash.utils.ByteArray;
-	#else
-	var b : Array<Int>;
-	#end
+	var b : BytesData;
+	#if !flash9
 	var pos : Int;
 	var len : Int;
+	#end
 
 	public function new( b : Bytes, ?pos : Int, ?len : Int ) {
 		if( pos == null ) pos = 0;
 		if( len == null ) len = b.length - pos;
-		if( pos < 0 || len < 0 || pos + len > b.length )
-			throw "Outside bounds";
-		this.b = untyped b.b;
+		if( pos < 0 || len < 0 || pos + len > b.length ) throw Error.OutsideBounds;
+		#if flash9
+		var ba = b.getData();
+		ba.position = pos;
+		if( len != ba.bytesAvailable ) {
+			// truncate
+			this.b = new flash.utils.ByteArray();
+			ba.readBytes(this.b,0,len);
+		} else
+			this.b = ba;
+		this.b.endian = flash.utils.Endian.LITTLE_ENDIAN;
+		#else
+		this.b = b.getData();
 		this.pos = pos;
 		this.len = len;
+		#end
+	}
+
+	public override function readByte() : Int {
+		#if flash9
+			return try b.readUnsignedByte() catch( e : Dynamic ) throw new Eof();
+		#else
+			if( this.len == 0 )
+				throw new Eof();
+			len--;
+			#if neko
+			return untyped __dollar__sget(b,pos++);
+			#else
+			return b[pos++];
+			#end
+		#end
 	}
 
-	public override function readChar() {
-		if( this.len == 0 )
-			throw new Eof();
-		#if neko
-		var c = untyped __dollar__sget(b.__s,pos++);
+	public override function readBytes( buf : Bytes, pos, len ) : Int {
+		#if !neko
+			if( pos < 0 || len < 0 || pos + len > b.length )
+				throw Error.OutsideBounds;
+		#end
+		#if flash9
+			try b.readBytes(buf.getData(),pos,len) catch( e : Dynamic ) throw new Eof();
 		#else
-		var c = b[pos++];
+			if( this.len == 0 && len > 0 )
+				throw new Eof();
+			if( this.len < len )
+				len = this.len;
+			#if neko
+			try untyped __dollar__sblit(buf.getData(),pos,b,this.pos,len) catch( e : Dynamic ) throw Error.OutsideBounds;
+			#else
+			var b1 = b;
+			var b2 = buf.getData();
+			for( i in 0...len )
+				b2[pos+i] = b1[this.pos+i];
+			#end
+			this.pos += len;
+			this.len -= len;
 		#end
-		len--;
-		return c;
+		return len;
+	}
+
+	#if flash9
+	override function setEndian(e) {
+		bigEndian = e;
+		b.endian = e ? flash.utils.Endian.BIG_ENDIAN : flash.utils.Endian.LITTLE_ENDIAN;
+		return e;
 	}
 
-	public override function readBytes( buf : Bytes, bpos, blen ) : Int {
-		if( len == 0 && blen > 0 )
-			throw new Eof();
-		if( len < blen )
-			blen = len;
-		untyped __dollar__sblit(buf.__s,bpos,s.__s,pos,blen);
-		pos += blen;
-		len -= blen;
-		return blen;
+	override function readFloat() {
+		return try b.readFloat() catch( e : Dynamic ) throw new Eof();
 	}
 
+	override function readDouble() {
+		return try b.readDouble() catch( e : Dynamic ) throw new Eof();
+	}
+	#end
+
 }

+ 17 - 1
std/haxe/io/BytesOutput.hx

@@ -32,7 +32,7 @@ class BytesOutput extends Output {
 		b = new BytesBuffer();
 	}
 
-	override function writeChar(c) {
+	override function writeByte(c) {
 		b.add(c);
 	}
 
@@ -41,6 +41,22 @@ class BytesOutput extends Output {
 		return blen;
 	}
 
+	#if flash9
+	override function setEndian(e) {
+		bigEndian = e;
+		untyped b.b.endian = e ? flash.utils.Endian.BIG_ENDIAN : flash.utils.Endian.LITTLE_ENDIAN;
+		return e;
+	}
+
+	override function writeFloat( f : Float ) {
+		untyped b.b.writeFloat(f);
+	}
+
+	override function writeDouble( f : Float ) {
+		untyped b.b.writeDouble(f);
+	}
+	#end
+
 	public function getBytes() {
 		return b.getBytes();
 	}

+ 3 - 1
std/haxe/io/Error.hx

@@ -30,8 +30,10 @@ package haxe.io;
 enum Error {
 	/** The IO is set into nonblocking mode and some data cannot be read or written **/
 	Blocked;
-	/** An operation is outside of its valid range **/
+	/** An integer value is outside its allowed range **/
 	Overflow;
+	/** An operation on Bytes is outside of its valid range **/
+	OutsideBounds;
 	/** Other errors **/
 	Custom( e : Dynamic );
 }

+ 4 - 9
std/haxe/io/Input.hx

@@ -38,10 +38,10 @@ class Input {
 
 	public function readBytes( s : Bytes, pos : Int, len : Int ) : Int {
 		var k = len;
-		var b = untyped s.b;
+		var b = s.getData();
 		#if !neko
 		if( pos < 0 || len < 0 || pos + len > s.length )
-			throw Error.Custom("Outside bounds");
+			throw Error.OutsideBounds;
 		#end
 		while( k > 0 ) {
 			#if neko
@@ -197,13 +197,8 @@ class Input {
 			ch3 = readByte();
 			ch4 = readByte();
 		}
-		if( (ch4 & 128) != 0 ) {
-			if( ch4 & 64 == 0 ) throw Error.Overflow;
-			return ch1 | (ch2 << 8) | (ch3 << 16) | ((ch4 & 127) << 24);
-		} else {
-			if( ch4 & 64 != 0 ) throw Error.Overflow;
-			return ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
-		}
+		if( ((ch4 & 128) != 0) != ((ch4 & 64) != 0) ) throw Error.Overflow;
+		return ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
 	}
 
 	public function readUInt31() {

+ 6 - 10
std/haxe/io/Output.hx

@@ -40,10 +40,10 @@ class Output {
 
 	public function writeBytes( s : Bytes, pos : Int, len : Int ) : Int {
 		var k = len;
-		var b = untyped s.b;
+		var b = s.getData();
 		#if !neko
 		if( pos < 0 || len < 0 || pos + len > s.length )
-			throw Error.Custom("Outside bounds");
+			throw Error.OutsideBounds;
 		#end
 		while( k > 0 ) {
 			#if neko
@@ -112,10 +112,8 @@ class Output {
 	}
 
 	public function writeInt16( x : Int ) {
-		if( x < 0 )
-			writeUInt16(0x10000 + x);
-		else
-			writeUInt16(x);
+		if( x < -0x8000 || x > 0x7FFF ) throw Error.Overflow;
+		writeUInt16(x & 0xFFFF);
 	}
 
 	public function writeUInt16( x : Int ) {
@@ -130,10 +128,8 @@ class Output {
 	}
 
 	public function writeInt24( x : Int ) {
-		if( x < 0 )
-			writeUInt24(0x1000000 + x);
-		else
-			writeUInt24(x);
+		if( x < -0x800000 || x > 0x7FFFFF ) throw Error.Overflow;
+		writeUInt24(x & 0xFFFFFF);
 	}
 
 	public function writeUInt24( x : Int ) {

+ 5 - 5
std/haxe/xml/Fast.hx

@@ -32,7 +32,7 @@ private class NodeAccess implements Dynamic<Fast> {
 		__x = x;
 	}
 
-	function __resolve( name : String ) : Fast {
+	public function resolve( name : String ) : Fast {
 		var x = __x.elementsNamed(name).next();
 		if( x == null ) {
 			var xname = if( __x.nodeType == Xml.Document ) "Document" else __x.nodeName;
@@ -51,7 +51,7 @@ private class AttribAccess implements Dynamic<String> {
 		__x = x;
 	}
 
-	function __resolve( name : String ) : String {
+	public function resolve( name : String ) : String {
 		if( __x.nodeType == Xml.Document )
 			throw "Cannot access document attribute "+name;
 		var v = __x.get(name);
@@ -70,7 +70,7 @@ private class HasAttribAccess implements Dynamic<Bool> {
 		__x = x;
 	}
 
-	function __resolve( name : String ) : Bool {
+	public function resolve( name : String ) : Bool {
 		if( __x.nodeType == Xml.Document )
 			throw "Cannot access document attribute "+name;
 		return __x.exists(name);
@@ -86,7 +86,7 @@ private class HasNodeAccess implements Dynamic<Bool> {
 		__x = x;
 	}
 
-	function __resolve( name : String ) : Bool {
+	public function resolve( name : String ) : Bool {
 		return __x.elementsNamed(name).hasNext();
 	}
 
@@ -100,7 +100,7 @@ private class NodeListAccess implements Dynamic<List<Fast>> {
 		__x = x;
 	}
 
-	function __resolve( name : String ) : List<Fast> {
+	public function resolve( name : String ) : List<Fast> {
 		var l = new List();
 		for( x in __x.elementsNamed(name) )
 			l.add(new Fast(x));

+ 1 - 1
std/haxe/xml/Proxy.hx

@@ -50,7 +50,7 @@ class Proxy<Const,T> {
 		this.__f = f;
 	}
 
-	function __resolve(k) {
+	public function resolve(k) {
 		return __f(k);
 	}
 

+ 3 - 1
tests/unit/Test.hx

@@ -66,8 +66,10 @@ class Test {
 			for( inst in classes ) {
 				current = Type.getClass(inst);
 				for( f in Type.getInstanceFields(current) )
-					if( f.substr(0,4) == "test" )
+					if( f.substr(0,4) == "test" ) {
 						Reflect.callMethod(inst,Reflect.field(inst,f),[]);
+						reportInfos = null;
+					}
 			}
 			report("DONE ["+count+" tests]",here);
 		} catch( e : Dynamic ) {

+ 8 - 3
tests/unit/TestBytes.hx

@@ -77,9 +77,8 @@ class TestBytes extends Test {
 		// toString
 		eq(b2.toString(),"ABCD");
 		// compare
-		var strings = ["ABCD","ABDC","ABCDE","ABC","BC","AAAAAAAAA",
-			#if !flash8 "" #end // there is an error with empty string comparison in Flash8
-		];
+		var strings = ["ABCD","ABDC","ABCDE","ABC","BC","AAAAAAAAA"];
+		// NOTE : Flash<9 has a bug when comparing with the empty string
 		for( s1 in strings )
 			for( s2 in strings ) {
 				var c = haxe.io.Bytes.ofString(s1).compare(haxe.io.Bytes.ofString(s2));
@@ -89,6 +88,12 @@ class TestBytes extends Test {
 				eq( c == 0, s1 == s2 );
 			}
 		infos(null);
+		// sub
+		var bs = haxe.io.Bytes.ofString("ABCDEFGH");
+		eq( bs.sub(1,3).compare(haxe.io.Bytes.ofString("BCD")), 0 );
+		exc(function() bs.sub(-1,3));
+		exc(function() bs.sub(1,-1));
+		exc(function() bs.sub(1,10));
 	}
 
 	function testBuffer() {

+ 81 - 1
tests/unit/TestIO.hx

@@ -1,8 +1,88 @@
-package unit;
+package unit;
 
 class TestIO extends Test {
 
 	public function test() {
+		check(false);
+		check(true);
+	}
+
+	function check(endian:Bool) {
+		infos("endian = "+endian);
+
+		var b = haxe.io.Bytes.ofString("ABCééé\r\n\t");
+		eq( b.length, 12 );
+		b.set(1,0);
+
+
+		var o = new haxe.io.BytesOutput();
+		o.bigEndian = endian;
+		eq(o.bigEndian,endian);
+
+		o.writeByte(0x00);
+		o.writeByte(0x01);
+		o.writeByte(0x02);
+		o.writeByte(0x03);
+
+		o.write(b);
+		o.writeByte(55);
+		o.writeBytes(b,3,5);
+		exc(function() o.writeBytes(b,-1,5));
+		exc(function() o.writeBytes(b,3,-1));
+		exc(function() o.writeBytes(b,3,20));
+
+		o.writeByte(98);
+		#if (neko || flash9)
+		o.writeDouble(1.23);
+		o.writeFloat(1.2e10);
+		#end
+		o.writeByte(99);
+
+		o.writeInt16(-12345);
+		exc(function() o.writeInt16(1 << 15));
+		exc(function() o.writeInt16(-((1 << 15)+1)));
+		o.writeInt24(-1234567);
+		exc(function() o.writeInt16(1 << 24));
+		exc(function() o.writeInt16(-((1 << 24)+1)));
+		o.writeInt31(-123456789);
+		o.writeInt8(-5);
+		exc(function() o.writeInt8(128));
+		exc(function() o.writeInt8(-129));
+		o.writeUInt16(0xFF55);
+		exc(function() o.writeUInt16(1 << 16));
+		exc(function() o.writeUInt16(-1));
+		o.writeUInt24(0xFF00EE);
+		exc(function() o.writeUInt24(1 << 24));
+		exc(function() o.writeUInt24(-1));
+		o.writeUInt31(0x3FAABBCC);
+
+		unspec(function() o.writeByte(-1));
+		unspec(function() o.writeByte(257));
+
+		var i = new haxe.io.BytesInput(o.getBytes());
+		i.bigEndian = endian;
+		eq( i.readUInt31(), endian ? 0x00010203 : 0x03020100 );
+		eq( i.read(b.length).compare(b) , 0 );
+		eq( i.readByte(), 55 );
+		eq( i.read(5).compare(b.sub(3,5)), 0 );
+
+		eq( i.readByte(), 98 );
+		#if (neko || flash9)
+		eq( i.readDouble(), 1.23 );
+		eq( i.readFloat(), 1.2e10 );
+		#else
+		exc(function() i.readDouble());
+		exc(function() i.readFloat());
+		#end
+		eq( i.readByte(), 99 );
+
+		eq( i.readInt16(), -12345 );
+		eq( i.readInt24(), -1234567 );
+		eq( i.readInt31(), -123456789 );
+		eq( i.readInt8(), -5 );
+		eq( i.readUInt16(), 0xFF55 );
+		eq( i.readUInt24(), 0xFF00EE );
+		eq( i.readUInt31(), 0x3FAABBCC );
 	}
 
 }

+ 4 - 4
typer.ml

@@ -275,7 +275,7 @@ let field_access ctx get f t e p =
 			AccSet (e,m,t,f.cf_name)
 	| ResolveAccess ->
 		let fstring = mk (TConst (TString f.cf_name)) (mk_mono()) p in
-		AccExpr (mk (TCall (mk (TField (e,"__resolve")) (mk_mono()) p,[fstring])) t p)
+		AccExpr (mk (TCall (mk (TField (e,"resolve")) (mk_mono()) p,[fstring])) t p)
 	| NeverAccess ->
 		AccNo f.cf_name
 	| InlineAccess ->
@@ -601,7 +601,7 @@ let extend_remoting ctx c t p async prot =
 					(EReturn (Some (EUntyped (ECall (
 						(EField (
 							(ECall (
-								(EField ((EConst (Ident "__cnx"),p),"__resolve"),p),
+								(EField ((EConst (Ident "__cnx"),p),"resolve"),p),
 								[if prot then idname else ECall ((EConst (Ident "__unprotect__"),p),[idname]),p]
 							),p)
 						,"call"),p),eargs
@@ -1214,8 +1214,8 @@ let type_field ctx e i p get =
 			match c.cl_dynamic with
 			| Some t ->
 				let t = apply_params c.cl_types params t in
-				if get && PMap.mem "__resolve" c.cl_fields then
-					AccExpr (mk (TCall (mk (TField (e,"__resolve")) (mk_mono()) p,[type_constant ctx (String i) p])) t p)
+				if get && PMap.mem "resolve" c.cl_fields then
+					AccExpr (mk (TCall (mk (TField (e,"resolve")) (mk_mono()) p,[type_constant ctx (String i) p])) t p)
 				else if not get && PMap.mem "__setfield" c.cl_fields then
 					AccSetField (e,i,t)
 				else