浏览代码

more binary support for js : use dataview for FPHelper, added dataview based BytesBuffer

Nicolas Cannasse 8 年之前
父节点
当前提交
1d3942208e
共有 2 个文件被更改,包括 133 次插入0 次删除
  1. 20 0
      std/haxe/io/FPHelper.hx
  2. 113 0
      std/js/_std/haxe/io/BytesBuffer.hx

+ 20 - 0
std/haxe/io/FPHelper.hx

@@ -54,6 +54,8 @@ class FPHelper {
 		}
 	#elseif php
 		static var isLittleEndian : Bool = untyped __call__('unpack','S','\x01\x00')[1] == 1;
+	#elseif js
+		static var helper = new js.html.DataView(new js.html.ArrayBuffer(8));
 	#else
 		static inline var LN2 = 0.6931471805599453; // Math.log(2)
 	#end
@@ -95,6 +97,9 @@ class FPHelper {
 			helper.writeUnsignedInt(i);
 			helper.position = 0;
 			return helper.readFloat();
+		#elseif js
+			helper.setInt32(0, i, true);
+			return helper.getFloat32(0, true);
 		#else
 			var sign = 1 - ((i >>> 31) << 1);
 			var exp = (i >>> 23) & 0xFF;
@@ -135,6 +140,9 @@ class FPHelper {
 			return helper.readUnsignedInt();
 		#elseif php
 			return untyped __call__('unpack','l',__call__('pack', 'f', f))[1];
+		#elseif js
+			helper.setFloat32(0, f, true);
+			return helper.getInt32(0,true);
 		#else
 			if( f == 0 ) return 0;
 			var af = f < 0 ? -f : f;
@@ -194,6 +202,10 @@ class FPHelper {
 			return helper.readDouble();
 		#elseif php
 			return untyped  __call__('unpack', 'd', __call__('pack', 'ii', isLittleEndian ? low : high, isLittleEndian ? high : low))[1];
+		#elseif js
+			helper.setInt32(0, low , true);
+			helper.setInt32(4, high, true);
+			return helper.getFloat64(0,true);
 		#else
 			#if python
 			if (low == 0 && high == 2146435072) {
@@ -280,6 +292,14 @@ class FPHelper {
 				i64.set_high(a[isLittleEndian ? 2 : 1]);
 			}
 			return i64;
+		#elseif js
+			var i64 = i64tmp;
+			helper.setFloat64(0, v, true);
+			@:privateAccess {
+				i64.set_low(helper.getInt32(0,true));
+				i64.set_high(helper.getInt32(4,true));
+			}
+			return i64;
 		#else
 			var i64 = i64tmp;
 			if( v == 0 ) {

+ 113 - 0
std/js/_std/haxe/io/BytesBuffer.hx

@@ -0,0 +1,113 @@
+/*
+ * Copyright (C)2005-2017 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;
+
+class BytesBuffer {
+
+	var buffer : js.html.ArrayBuffer;
+	var view : js.html.DataView;
+	var u8 : js.html.Uint8Array;
+	var pos : Int;
+	var size : Int;
+
+	public var length(get,never) : Int;
+
+	public function new() {
+		pos = 0;
+		size = 0;
+	}
+
+	inline function get_length() : Int {
+		return pos;
+	}
+
+	public function addByte( byte : Int ) {
+		if( pos == size ) grow(1);
+		view.setUint8(pos++, byte);
+	}
+
+	public function add( src : Bytes ) {
+		if( pos + src.length > size ) grow(src.length);
+		var sub = new js.html.Uint8Array(@:privateAccess src.b.buffer, @:privateAccess src.b.byteOffset, src.length);
+		u8.set(sub, pos);
+		pos += src.length;
+	}
+
+	public function addString( v : String ) {
+		add(Bytes.ofString(v));
+	}
+
+	public function addInt32( v : Int ) {
+		if( pos + 4 > size ) grow(4);
+		view.setInt32(pos, v, true);
+		pos += 4;
+	}
+
+	public function addInt64( v : haxe.Int64 ) {
+		if( pos + 8 > size ) grow(8);
+		view.setInt32(pos, v.low, true);
+		view.setInt32(pos + 4, v.high, true);
+		pos += 8;
+	}
+
+	public function addFloat( v : Float ) {
+		if( pos + 4 > size ) grow(4);
+		view.setFloat32(pos, v, true);
+		pos += 4;
+	}
+
+	public function addDouble( v : Float ) {
+		if( pos + 8 > size ) grow(8);
+		view.setFloat64(pos, v, true);
+		pos += 8;
+	}
+
+	public function addBytes( src : Bytes, pos : Int, len : Int ) {
+		if( pos < 0 || len < 0 || pos + len > src.length ) throw Error.OutsideBounds;
+		if( this.pos + len > size ) grow(len);
+		var sub = new js.html.Uint8Array(@:privateAccess src.b.buffer, @:privateAccess src.b.byteOffset + pos, len);
+		u8.set(sub, this.pos);
+		this.pos += len;
+	}
+
+	function grow( delta : Int ) {
+		var req = pos + delta;
+		var nsize = size == 0 ? 16 : size;
+		while( nsize < req )
+			nsize = (nsize * 3) >> 1;
+		var nbuf = new js.html.ArrayBuffer(nsize);
+		var nu8 = new js.html.Uint8Array(nbuf);
+		if( size > 0 )
+			nu8.set(u8);
+		size = nsize;
+		buffer = nbuf;
+		u8 = nu8;
+		view = new js.html.DataView(buffer);
+	}
+
+	public function getBytes() : Bytes @:privateAccess {
+		var b = new Bytes(buffer);
+		b.length = pos;
+		return b;
+	}
+
+}