/bin/std/haxe/io/Bytes.hx

http://github.com/Yoomee/clippy · Haxe · 290 lines · 235 code · 15 blank · 40 comment · 41 complexity · 38ba62611f8dbc91952782fca10d89b4 MD5 · raw file

  1. /*
  2. * Copyright (c) 2005-2008, The haXe Project Contributors
  3. * All rights reserved.
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * - Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * - Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
  17. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  19. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  20. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  23. * DAMAGE.
  24. */
  25. package haxe.io;
  26. class Bytes {
  27. public var length(default,null) : Int;
  28. var b : BytesData;
  29. function new(length,b) {
  30. this.length = length;
  31. this.b = b;
  32. }
  33. public inline function get( pos : Int ) : Int {
  34. #if neko
  35. return untyped __dollar__sget(b,pos);
  36. #elseif flash9
  37. return b[pos];
  38. #elseif php
  39. return untyped __call__("ord", b[pos]);
  40. #elseif cpp
  41. return untyped b[pos];
  42. #else
  43. return b[pos];
  44. #end
  45. }
  46. public inline function set( pos : Int, v : Int ) : Void {
  47. #if neko
  48. untyped __dollar__sset(b,pos,v);
  49. #elseif flash9
  50. b[pos] = v;
  51. #elseif php
  52. b[pos] = untyped __call__("chr", v);
  53. #elseif cpp
  54. untyped b[pos] = v;
  55. #else
  56. b[pos] = v & 0xFF;
  57. #end
  58. }
  59. public function blit( pos : Int, src : Bytes, srcpos : Int, len : Int ) : Void {
  60. #if !neko
  61. if( pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length ) throw Error.OutsideBounds;
  62. #end
  63. #if neko
  64. try untyped __dollar__sblit(b,pos,src.b,srcpos,len) catch( e : Dynamic ) throw Error.OutsideBounds;
  65. #elseif php
  66. // TODO: test me
  67. b = untyped __php__("substr($this->b, 0, $pos) . substr($src->b, $srcpos, $len) . substr($this->b, $pos+$len)"); //__call__("substr", b, 0, pos)+__call__("substr", src.b, srcpos, len)+__call__("substr", b, pos+len);
  68. #elseif flash9
  69. b.position = pos;
  70. b.writeBytes(src.b,srcpos,len);
  71. #else
  72. var b1 = b;
  73. var b2 = src.b;
  74. if( b1 == b2 && pos > srcpos ) {
  75. var i = len;
  76. while( i > 0 ) {
  77. i--;
  78. b1[i + pos] = b2[i + srcpos];
  79. }
  80. return;
  81. }
  82. for( i in 0...len )
  83. b1[i+pos] = b2[i+srcpos];
  84. #end
  85. }
  86. public function sub( pos : Int, len : Int ) : Bytes {
  87. #if !neko
  88. if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
  89. #end
  90. #if neko
  91. return try new Bytes(len,untyped __dollar__ssub(b,pos,len)) catch( e : Dynamic ) throw Error.OutsideBounds;
  92. #elseif flash9
  93. b.position = pos;
  94. var b2 = new flash.utils.ByteArray();
  95. b.readBytes(b2,0,len);
  96. return new Bytes(len,b2);
  97. #elseif php
  98. // TODO: test me
  99. return new Bytes(len, untyped __call__("substr", b, pos, len));
  100. #else
  101. return new Bytes(len,b.slice(pos,pos+len));
  102. #end
  103. }
  104. public function compare( other : Bytes ) : Int {
  105. #if neko
  106. return untyped __dollar__compare(b,other.b);
  107. #elseif flash9
  108. var len = (length < other.length) ? length : other.length;
  109. var b1 = b;
  110. var b2 = other.b;
  111. b1.position = 0;
  112. b2.position = 0;
  113. for( i in 0...len>>2 )
  114. if( b1.readUnsignedInt() != b2.readUnsignedInt() ) {
  115. b1.position -= 4;
  116. b2.position -= 4;
  117. return b1.readUnsignedInt() - b2.readUnsignedInt();
  118. }
  119. for( i in 0...len & 3 )
  120. if( b1.readUnsignedByte() != b2.readUnsignedByte() )
  121. return b1[b1.position-1] - b2[b2.position-1];
  122. return length - other.length;
  123. #elseif php
  124. return untyped __php__("$this->b < $other->b ? -1 : ($this->b == $other->b ? 0 : 1)");
  125. #else
  126. var b1 = b;
  127. var b2 = other.b;
  128. var len = (length < other.length) ? length : other.length;
  129. for( i in 0...len )
  130. if( b1[i] != b2[i] )
  131. #if cpp
  132. return untyped b1[i] - untyped b2[i];
  133. #else
  134. return b1[i] - b2[i];
  135. #end
  136. return length - other.length;
  137. #end
  138. }
  139. public function readString( pos : Int, len : Int ) : String {
  140. #if !neko
  141. if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
  142. #end
  143. #if neko
  144. return try new String(untyped __dollar__ssub(b,pos,len)) catch( e : Dynamic ) throw Error.OutsideBounds;
  145. #elseif flash9
  146. b.position = pos;
  147. return b.readUTFBytes(len);
  148. #elseif php
  149. // TODO: test me
  150. return untyped __call__("substr", b, pos, len);
  151. // return untyped __call__("call_user_func_array", "pack", __call__("array_merge", __call__("array", "C*"), __call__("array_slice", b.»a, pos, len)));
  152. #elseif cpp
  153. var result:String="";
  154. untyped __global__.__hxcpp_string_of_bytes(b,result,pos,len);
  155. return result;
  156. #else
  157. var s = "";
  158. var b = b;
  159. var fcc = String.fromCharCode;
  160. var i = pos;
  161. var max = pos+len;
  162. // utf8-encode
  163. while( i < max ) {
  164. var c = b[i++];
  165. if( c < 0x80 ) {
  166. if( c == 0 ) break;
  167. s += fcc(c);
  168. } else if( c < 0xE0 )
  169. s += fcc( ((c & 0x3F) << 6) | (b[i++] & 0x7F) );
  170. else if( c < 0xF0 ) {
  171. var c2 = b[i++];
  172. s += fcc( ((c & 0x1F) << 12) | ((c2 & 0x7F) << 6) | (b[i++] & 0x7F) );
  173. } else {
  174. var c2 = b[i++];
  175. var c3 = b[i++];
  176. s += fcc( ((c & 0x0F) << 18) | ((c2 & 0x7F) << 12) | ((c3 << 6) & 0x7F) | (b[i++] & 0x7F) );
  177. }
  178. }
  179. return s;
  180. #end
  181. }
  182. public function toString() : String {
  183. #if neko
  184. return new String(untyped __dollar__ssub(b,0,length));
  185. #elseif flash9
  186. b.position = 0;
  187. return b.readUTFBytes(length);
  188. #elseif php
  189. // TODO: test me
  190. return cast b;
  191. // return untyped __call__("call_user_func_array", "pack", __call__("array_merge", __call__("array", "C*"), b.»a));
  192. #else
  193. return readString(0,length);
  194. #end
  195. }
  196. public inline function getData() : BytesData {
  197. return b;
  198. }
  199. public static function alloc( length : Int ) : Bytes {
  200. #if neko
  201. return new Bytes(length,untyped __dollar__smake(length));
  202. #elseif flash9
  203. var b = new flash.utils.ByteArray();
  204. b.length = length;
  205. return new Bytes(length,b);
  206. #elseif php
  207. // TODO: test me
  208. return new Bytes(length, untyped __call__("str_repeat", __call__("chr", 0), length));
  209. /*
  210. if(length > 0)
  211. return new Bytes(length, untyped __call__("new _hx_array", __call__("array_fill", 0, length, 0)));
  212. else
  213. return new Bytes(0, untyped __call__("new _hx_array", __call__("array")));
  214. */
  215. #elseif cpp
  216. var a = new BytesData();
  217. if (length>0) a[length-1] = untyped 0;
  218. return new Bytes(length,a);
  219. #else
  220. var a = new Array();
  221. for( i in 0...length )
  222. a.push(0);
  223. return new Bytes(length,a);
  224. #end
  225. }
  226. public static function ofString( s : String ) : Bytes {
  227. #if neko
  228. return new Bytes(s.length,untyped __dollar__ssub(s.__s,0,s.length));
  229. #elseif flash9
  230. var b = new flash.utils.ByteArray();
  231. b.writeUTFBytes(s);
  232. return new Bytes(b.length,b);
  233. #elseif php
  234. return new Bytes(untyped __call__("strlen", s), cast s);
  235. // return ofData(untyped __call__("new _hx_array", __call__("array_values", __call__("unpack", "C*", s))));
  236. #elseif cpp
  237. var a = new BytesData();
  238. untyped __global__.__hxcpp_bytes_of_string(a,s);
  239. return new Bytes(a.length,a);
  240. #else
  241. var a = new Array();
  242. // utf8-decode
  243. for( i in 0...s.length ) {
  244. var c : Int = untyped s["cca"](i);
  245. if( c <= 0x7F )
  246. a.push(c);
  247. else if( c <= 0x7FF ) {
  248. a.push( 0xC0 | (c >> 6) );
  249. a.push( 0x80 | (c & 63) );
  250. } else if( c <= 0xFFFF ) {
  251. a.push( 0xE0 | (c >> 12) );
  252. a.push( 0x80 | ((c >> 6) & 63) );
  253. a.push( 0x80 | (c & 63) );
  254. } else {
  255. a.push( 0xF0 | (c >> 18) );
  256. a.push( 0x80 | ((c >> 12) & 63) );
  257. a.push( 0x80 | ((c >> 6) & 63) );
  258. a.push( 0x80 | (c & 63) );
  259. }
  260. }
  261. return new Bytes(a.length,a);
  262. #end
  263. }
  264. public static function ofData( b : BytesData ) {
  265. #if flash9
  266. return new Bytes(b.length,b);
  267. #elseif neko
  268. return new Bytes(untyped __dollar__ssize(b),b);
  269. #elseif php
  270. return new Bytes(untyped __call__("strlen", b), b);
  271. #else
  272. return new Bytes(b.length,b);
  273. #end
  274. }
  275. }