BytesInput.hx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Copyright (C)2005-2019 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. package haxe.io;
  23. class BytesInput extends Input {
  24. var b:#if js js.lib.Uint8Array #elseif hl hl.Bytes #else BytesData #end;
  25. #if !flash
  26. var pos:Int;
  27. var len:Int;
  28. var totlen:Int;
  29. #end
  30. /** The current position in the stream in bytes. */
  31. public var position(get, set):Int;
  32. /** The length of the stream in bytes. */
  33. public var length(get, never):Int;
  34. public function new(b:Bytes, ?pos:Int, ?len:Int) {
  35. if (pos == null)
  36. pos = 0;
  37. if (len == null)
  38. len = b.length - pos;
  39. if (pos < 0 || len < 0 || pos + len > b.length)
  40. throw Error.OutsideBounds;
  41. #if flash
  42. var ba = b.getData();
  43. ba.position = pos;
  44. if (len != ba.bytesAvailable) {
  45. // truncate
  46. this.b = new flash.utils.ByteArray();
  47. ba.readBytes(this.b, 0, len);
  48. } else
  49. this.b = ba;
  50. this.b.endian = flash.utils.Endian.LITTLE_ENDIAN;
  51. #else
  52. this.b = #if (js || hl) @:privateAccess b.b #else b.getData() #end;
  53. this.pos = pos;
  54. this.len = len;
  55. this.totlen = len;
  56. #end
  57. #if python
  58. bigEndian = false;
  59. #end
  60. }
  61. inline function get_position():Int {
  62. #if flash
  63. return b.position;
  64. #else
  65. return pos;
  66. #end
  67. }
  68. inline function get_length():Int {
  69. #if flash
  70. return b.length;
  71. #else
  72. return totlen;
  73. #end
  74. }
  75. function set_position(p:Int):Int {
  76. if (p < 0)
  77. p = 0;
  78. else if (p > length)
  79. p = length;
  80. #if flash
  81. return b.position = p;
  82. #else
  83. len = totlen - p;
  84. return pos = p;
  85. #end
  86. }
  87. public override function readByte():Int {
  88. #if flash
  89. return try b.readUnsignedByte() catch (e:Dynamic) throw new Eof();
  90. #else
  91. if (this.len == 0)
  92. throw new Eof();
  93. len--;
  94. #if neko
  95. return untyped __dollar__sget(b, pos++);
  96. #elseif cpp
  97. return untyped b[pos++];
  98. #elseif java
  99. return untyped b[pos++] & 0xFF;
  100. #elseif python // dodge https://github.com/HaxeFoundation/haxe/issues/5080
  101. var b = b[pos];
  102. pos++;
  103. return b;
  104. #else
  105. return b[pos++];
  106. #end
  107. #end
  108. }
  109. public override function readBytes(buf:Bytes, pos:Int, len:Int):Int {
  110. #if !neko
  111. if (pos < 0 || len < 0 || pos + len > buf.length)
  112. throw Error.OutsideBounds;
  113. #end
  114. #if flash
  115. var avail:Int = b.bytesAvailable;
  116. if (len > avail && avail > 0)
  117. len = avail;
  118. try
  119. b.readBytes(buf.getData(), pos, len)
  120. catch (e:Dynamic)
  121. throw new Eof();
  122. #elseif java
  123. var avail:Int = this.len;
  124. if (len > avail)
  125. len = avail;
  126. if (len == 0)
  127. throw new Eof();
  128. java.lang.System.arraycopy(this.b, this.pos, buf.getData(), pos, len);
  129. this.pos += len;
  130. this.len -= len;
  131. #else
  132. if (this.len == 0 && len > 0)
  133. throw new Eof();
  134. if (this.len < len)
  135. len = this.len;
  136. #if neko
  137. try
  138. untyped __dollar__sblit(buf.getData(), pos, b, this.pos, len)
  139. catch (e:Dynamic)
  140. throw Error.OutsideBounds;
  141. #elseif hl
  142. @:privateAccess buf.b.blit(pos, b, this.pos, len);
  143. #else
  144. var b1 = b;
  145. var b2 = #if js @:privateAccess buf.b #else buf.getData() #end;
  146. for (i in 0...len)
  147. b2[pos + i] = b1[this.pos + i];
  148. #end
  149. this.pos += len;
  150. this.len -= len;
  151. #end
  152. return len;
  153. }
  154. #if flash
  155. @:dox(hide)
  156. override function set_bigEndian(e) {
  157. bigEndian = e;
  158. b.endian = e ? flash.utils.Endian.BIG_ENDIAN : flash.utils.Endian.LITTLE_ENDIAN;
  159. return e;
  160. }
  161. @:dox(hide)
  162. override function readFloat() {
  163. return try b.readFloat() catch (e:Dynamic) throw new Eof();
  164. }
  165. @:dox(hide)
  166. override function readDouble() {
  167. return try b.readDouble() catch (e:Dynamic) throw new Eof();
  168. }
  169. @:dox(hide)
  170. override function readInt8() {
  171. return try b.readByte() catch (e:Dynamic) throw new Eof();
  172. }
  173. @:dox(hide)
  174. override function readInt16() {
  175. return try b.readShort() catch (e:Dynamic) throw new Eof();
  176. }
  177. @:dox(hide)
  178. override function readUInt16():Int {
  179. return try b.readUnsignedShort() catch (e:Dynamic) throw new Eof();
  180. }
  181. @:dox(hide)
  182. override function readInt32():Int {
  183. return try b.readInt() catch (e:Dynamic) throw new Eof();
  184. }
  185. @:dox(hide)
  186. override function readString(len:Int, ?encoding:Encoding) {
  187. return try encoding == RawNative ? b.readMultiByte(len, "unicode") : b.readUTFBytes(len) catch (e:Dynamic) throw new Eof();
  188. }
  189. #end
  190. }