Bläddra i källkod

Merge branch 'development' of github.com:HaxeFoundation/haxe into development

Nicolas Cannasse 10 år sedan
förälder
incheckning
18a070b7e2

+ 2 - 0
std/haxe/io/BytesBuffer.hx

@@ -188,6 +188,8 @@ class BytesBuffer {
 		#elseif python
 		var buf = python.lib.Builtin.bytearray(b);
 		var bytes = new Bytes(buf.length, buf);
+		#elseif js
+		var bytes = new Bytes(b.length,new BytesData(b));
 		#else
 		var bytes = new Bytes(b.length,b);
 		#end

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

@@ -36,6 +36,8 @@ package haxe.io;
 	typedef BytesData = cs.NativeArray<cs.StdTypes.UInt8>;
 #elseif python
 	typedef BytesData = python.lib.ByteArray;
+#elseif js
+	typedef BytesData = js.html.Uint8Array;
 #else
 	typedef BytesData = Array<Int>;
 #end

+ 195 - 0
std/js/_std/haxe/io/Bytes.hx

@@ -0,0 +1,195 @@
+/*
+ * Copyright (C)2005-2014 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package haxe.io;
+import js.html.compat.Uint8Array;
+
+@:coreApi
+class Bytes {
+
+	public var length(default,null) : Int;
+	var b : BytesData;
+	var data : js.html.DataView;
+
+	function new(length:Int,b:BytesData) {
+		this.length = length;
+		this.b = b;
+	}
+
+	public inline function get( pos : Int ) : Int {
+		return b[pos];
+	}
+
+	public inline function set( pos : Int, v : Int ) : Void {
+		b[pos] = v & 0xFF; // the &0xFF is necessary for js.html.compat support
+	}
+
+	public function blit( pos : Int, src : Bytes, srcpos : Int, len : Int ) : Void {
+		if( pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length ) throw Error.OutsideBounds;
+		if( srcpos == 0 && len == src.length )
+			b.set(src.b,pos);
+		else
+			b.set(src.b.subarray(srcpos,srcpos+len),pos);
+	}
+
+	public function fill( pos : Int, len : Int, value : Int ) : Void {
+		for( i in 0...len )
+			set(pos++, value);
+	}
+
+	public function sub( pos : Int, len : Int ) : Bytes {
+		if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
+		return new Bytes(len,new BytesData(b.buffer.slice(pos+b.byteOffset,pos+b.byteOffset+len)));
+	}
+
+	public function compare( other : Bytes ) : Int {
+		var b1 = b;
+		var b2 = other.b;
+		var len = (length < other.length) ? length : other.length;
+		for( i in 0...len )
+			if( b1[i] != b2[i] )
+				return b1[i] - b2[i];
+		return length - other.length;
+	}
+
+	inline function initData() : Void {
+		if( data == null ) data = new js.html.DataView(b.buffer, b.byteOffset, b.byteLength);
+	}
+	
+	public function getDouble( pos : Int ) : Float {
+		initData();
+		return data.getFloat64(pos, false);
+	}
+
+	public function getFloat( pos : Int ) : Float {
+		initData();
+		return data.getFloat32(pos, false);
+	}
+
+	public function setDouble( pos : Int, v : Float ) : Void {
+		initData();
+		data.setFloat64(pos, v, false);
+	}
+
+	public function setFloat( pos : Int, v : Float ) : Void {
+		initData();
+		data.setFloat32(pos, v, false);
+	}
+
+	public function getString( pos : Int, len : Int ) : String {
+		if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
+		var s = "";
+		var b = b;
+		var fcc = String.fromCharCode;
+		var i = pos;
+		var max = pos+len;
+		// utf8-decode and utf16-encode
+		while( i < max ) {
+			var c = b[i++];
+			if( c < 0x80 ) {
+				if( c == 0 ) break;
+				s += fcc(c);
+			} else if( c < 0xE0 )
+				s += fcc( ((c & 0x3F) << 6) | (b[i++] & 0x7F) );
+			else if( c < 0xF0 ) {
+				var c2 = b[i++];
+				s += fcc( ((c & 0x1F) << 12) | ((c2 & 0x7F) << 6) | (b[i++] & 0x7F) );
+			} else {
+				var c2 = b[i++];
+				var c3 = b[i++];
+				var u = ((c & 0x0F) << 18) | ((c2 & 0x7F) << 12) | ((c3 & 0x7F) << 6) | (b[i++] & 0x7F);
+				// surrogate pair
+				s += fcc( (u >> 10) + 0xD7C0 );
+				s += fcc( (u & 0x3FF) | 0xDC00 );
+			}
+		}
+		return s;
+	}
+
+	@:deprecated("readString is deprecated, use getString instead")
+	@:noCompletion
+	public inline function readString(pos:Int, len:Int):String {
+		return getString(pos, len);
+	}
+
+	public function toString() : String {
+		return getString(0,length);
+	}
+
+	public function toHex() : String {
+		var s = new StringBuf();
+		var chars = [];
+		var str = "0123456789abcdef";
+		for( i in 0...str.length )
+			chars.push(str.charCodeAt(i));
+		for( i in 0...length ) {
+			var c = get(i);
+			s.addChar(chars[c >> 4]);
+			s.addChar(chars[c & 15]);
+		}
+		return s.toString();
+	}
+
+	public inline function getData() : BytesData {
+		return b;
+	}
+
+	public static function alloc( length : Int ) : Bytes {
+		return new Bytes(length,new BytesData(length));
+	}
+
+	public static function ofString( s : String ) : Bytes {
+		var a = new Array();
+		// utf16-decode and utf8-encode
+		var i = 0;
+		while( i < s.length ) {
+			var c : Int = StringTools.fastCodeAt(s,i++);
+			// surrogate pair
+			if( 0xD800 <= c && c <= 0xDBFF )
+			    c = (c - 0xD7C0 << 10) | (StringTools.fastCodeAt(s,i++) & 0x3FF);
+			if( c <= 0x7F )
+				a.push(c);
+			else if( c <= 0x7FF ) {
+				a.push( 0xC0 | (c >> 6) );
+				a.push( 0x80 | (c & 63) );
+			} else if( c <= 0xFFFF ) {
+				a.push( 0xE0 | (c >> 12) );
+				a.push( 0x80 | ((c >> 6) & 63) );
+				a.push( 0x80 | (c & 63) );
+			} else {
+				a.push( 0xF0 | (c >> 18) );
+				a.push( 0x80 | ((c >> 12) & 63) );
+				a.push( 0x80 | ((c >> 6) & 63) );
+				a.push( 0x80 | (c & 63) );
+			}
+		}
+		return new Bytes(a.length,new BytesData(a));
+	}
+
+	public static function ofData( b : BytesData ) : Bytes {
+		return new Bytes(b.length,b);
+	}
+
+	public inline static function fastGet( b : BytesData, pos : Int ) : Int {
+		return b[pos];
+	}
+
+}

+ 54 - 0
std/js/html/compat/ArrayBuffer.hx

@@ -0,0 +1,54 @@
+/*
+ * Copyright (C)2005-2014 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package js.html.compat;
+
+@:keep
+class ArrayBuffer {
+
+	public var byteLength : Int;
+	var a : Array<Dynamic>;
+	
+	public function new( ?a : Dynamic ) {
+		if( Std.is(a,Array) ) {
+			this.a = a;
+			byteLength = a.length;
+		} else
+			throw "TODO";
+	}
+	
+	public function slice(begin,?end) {
+		return new ArrayBuffer(a.slice(begin,end));
+	}
+	
+	static function sliceImpl(begin,?end) {
+		var u = new js.html.Uint8Array(untyped __js__('this'), begin, end == null ? null : end - begin);
+        var result = new js.html.ArrayBuffer(u.byteLength);
+        var resultArray = new js.html.Uint8Array(result);
+		resultArray.set(u);
+        return result;
+	}
+
+	static function __init__() untyped {
+		var ArrayBuffer = __js__('typeof(window) != "undefined" && window.ArrayBuffer') || ArrayBuffer;
+		if( ArrayBuffer.prototype.slice == null ) ArrayBuffer.prototype.slice = sliceImpl; // IE10
+	}
+}

+ 98 - 0
std/js/html/compat/Uint8Array.hx

@@ -0,0 +1,98 @@
+/*
+ * Copyright (C)2005-2014 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package js.html.compat;
+
+@:keep
+class Uint8Array {
+
+	static var BYTES_PER_ELEMENT = 1;
+
+	static function _new( ?arg1 : Dynamic, ?offset : Int, ?length : Int ) {
+		var arr;
+		if( untyped __typeof__(arg1) == 'number' ) {
+			arr = new Array();
+			for( i in 0...arg1 )
+				arr[i] = 0;
+			untyped {
+				arr.byteLength = arr.length;
+				arr.byteOffset = 0;
+				arr.buffer = new ArrayBuffer(arr);
+			}
+		} else if( Std.is(arg1,ArrayBuffer) ) {
+			var buffer : ArrayBuffer = arg1;
+			if( offset == null ) offset = 0;
+			if( length == null ) length = buffer.byteLength - offset;
+			if( offset == 0 )
+				arr = cast @:privateAccess buffer.a;
+			else
+				// here we are losing the fact that we should reference the same data,
+				// but I don't see another way to have this behaviour while keeping [] access
+				arr = cast @:privateAccess buffer.a.slice(offset, offset+length);
+			untyped {
+				arr.byteLength = arr.length;
+				arr.byteOffset = offset;
+				arr.buffer = buffer;
+			}
+		} else if( Std.is(arg1, Array) ) {
+			arr = (arg1 : Array<Int>).copy();
+			untyped {
+				arr.byteLength = arr.length;
+				arr.byteOffset = 0;
+				arr.buffer = new ArrayBuffer(arr);
+			}
+		} else
+			throw "TODO";
+		untyped {
+			arr.subarray = _subarray;
+			arr.set = _set;
+		}
+		return arr;
+	}
+
+	static function _set( ?arg : Dynamic, ?offset : Int ) {
+		var t : Dynamic = untyped __js__("this");
+		if( Std.is(arg.buffer,ArrayBuffer) ) {
+			var a : Array<Int> = arg;
+			if( arg.byteLength + offset > t.byteLength )
+				throw "set() outside of range";
+			for( i in 0...arg.byteLength )
+				t[i + offset] = a[i];
+		} else if( Std.is(arg,Array) ) {
+			var a : Array<Int> = arg;
+			if( a.length + offset > t.byteLength )
+				throw "set() outside of range";
+			for( i in 0...a.length )
+				t[i + offset] = a[i];
+		} else
+			throw "TODO";
+	}
+
+	static function _subarray( start : Int, ?end : Int ) {
+		var t : Dynamic = untyped __js__("this");
+		return _new(t.buffer, start + t.byteOffset, (end == null ? null : end - start));
+	}
+
+	static function __init__() untyped {
+		var Uint8Array = __js__('typeof(window) != "undefined" && window.Uint8Array') || _new;
+	}
+
+}