Output.hx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /*
  2. * Copyright (C)2005-2017 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. /**
  24. An Output is an abstract write. A specific output implementation will only
  25. have to override the `writeByte` and maybe the `write`, `flush` and `close`
  26. methods. See `File.write` and `String.write` for two ways of creating an
  27. Output.
  28. **/
  29. class Output {
  30. /**
  31. Endianness (word byte order) used when writing numbers.
  32. If `true`, big-endian is used, otherwise `little-endian` is used.
  33. **/
  34. public var bigEndian(default, set) : Bool;
  35. #if java
  36. private var helper:java.nio.ByteBuffer;
  37. #end
  38. /**
  39. Write one byte.
  40. **/
  41. public function writeByte( c : Int ) : Void {
  42. throw "Not implemented";
  43. }
  44. /**
  45. Write `len` bytes from `s` starting by position specified by `pos`.
  46. Returns the actual length of written data that can differ from `len`.
  47. See `writeFullBytes` that tries to write the exact amount of specified bytes.
  48. **/
  49. public function writeBytes( s : Bytes, pos : Int, len : Int ) : Int {
  50. #if !neko
  51. if( pos < 0 || len < 0 || pos + len > s.length )
  52. throw Error.OutsideBounds;
  53. #end
  54. var b = #if js @:privateAccess s.b #else s.getData() #end;
  55. var k = len;
  56. while( k > 0 ) {
  57. #if neko
  58. writeByte(untyped __dollar__sget(b,pos));
  59. #elseif php
  60. writeByte(b.get(pos));
  61. #elseif cpp
  62. writeByte(untyped b[pos]);
  63. #elseif hl
  64. writeByte(b[pos]);
  65. #else
  66. writeByte(untyped b[pos]);
  67. #end
  68. pos++;
  69. k--;
  70. }
  71. return len;
  72. }
  73. /**
  74. Flush any buffered data.
  75. **/
  76. public function flush() {
  77. }
  78. /**
  79. Close the output.
  80. Behaviour while writing after calling this method is unspecified.
  81. **/
  82. public function close() {
  83. }
  84. function set_bigEndian( b ) {
  85. bigEndian = b;
  86. return b;
  87. }
  88. /* ------------------ API ------------------ */
  89. /**
  90. Write all bytes stored in `s`.
  91. **/
  92. public function write( s : Bytes ) : Void {
  93. var l = s.length;
  94. var p = 0;
  95. while( l > 0 ) {
  96. var k = writeBytes(s,p,l);
  97. if( k == 0 ) throw Error.Blocked;
  98. p += k;
  99. l -= k;
  100. }
  101. }
  102. /**
  103. Write `len` bytes from `s` starting by position specified by `pos`.
  104. Unlike `writeBytes`, this method tries to write the exact `len` amount of bytes.
  105. **/
  106. public function writeFullBytes( s : Bytes, pos : Int, len : Int ) {
  107. while( len > 0 ) {
  108. var k = writeBytes(s,pos,len);
  109. pos += k;
  110. len -= k;
  111. }
  112. }
  113. /**
  114. Write `x` as 32-bit floating point number.
  115. Endianness is specified by the `bigEndian` property.
  116. **/
  117. public function writeFloat( x : Float ) {
  118. writeInt32(FPHelper.floatToI32(x));
  119. }
  120. /**
  121. Write `x` as 64-bit double-precision floating point number.
  122. Endianness is specified by the `bigEndian` property.
  123. **/
  124. public function writeDouble( x : Float ) {
  125. var i64 = FPHelper.doubleToI64(x);
  126. if( bigEndian ) {
  127. writeInt32(i64.high);
  128. writeInt32(i64.low);
  129. } else {
  130. writeInt32(i64.low);
  131. writeInt32(i64.high);
  132. }
  133. }
  134. /**
  135. Write `x` as 8-bit signed integer.
  136. **/
  137. public function writeInt8( x : Int ) {
  138. if( x < -0x80 || x >= 0x80 )
  139. throw Error.Overflow;
  140. writeByte(x & 0xFF);
  141. }
  142. /**
  143. Write `x` as 16-bit signed integer.
  144. Endianness is specified by the `bigEndian` property.
  145. **/
  146. public function writeInt16( x : Int ) {
  147. if( x < -0x8000 || x >= 0x8000 ) throw Error.Overflow;
  148. writeUInt16(x & 0xFFFF);
  149. }
  150. /**
  151. Write `x` as 16-bit unsigned integer.
  152. Endianness is specified by the `bigEndian` property.
  153. **/
  154. public function writeUInt16( x : Int ) {
  155. if( x < 0 || x >= 0x10000 ) throw Error.Overflow;
  156. if( bigEndian ) {
  157. writeByte(x >> 8);
  158. writeByte(x & 0xFF);
  159. } else {
  160. writeByte(x & 0xFF);
  161. writeByte(x >> 8);
  162. }
  163. }
  164. /**
  165. Write `x` as 24-bit signed integer.
  166. Endianness is specified by the `bigEndian` property.
  167. **/
  168. public function writeInt24( x : Int ) {
  169. if( x < -0x800000 || x >= 0x800000 ) throw Error.Overflow;
  170. writeUInt24(x & 0xFFFFFF);
  171. }
  172. /**
  173. Write `x` as 24-bit unsigned integer.
  174. Endianness is specified by the `bigEndian` property.
  175. **/
  176. public function writeUInt24( x : Int ) {
  177. if( x < 0 || x >= 0x1000000 ) throw Error.Overflow;
  178. if( bigEndian ) {
  179. writeByte(x >> 16);
  180. writeByte((x >> 8) & 0xFF);
  181. writeByte(x & 0xFF);
  182. } else {
  183. writeByte(x & 0xFF);
  184. writeByte((x >> 8) & 0xFF);
  185. writeByte(x >> 16);
  186. }
  187. }
  188. /**
  189. Write `x` as 32-bit signed integer.
  190. Endianness is specified by the `bigEndian` property.
  191. **/
  192. public function writeInt32( x : Int ) {
  193. if( bigEndian ) {
  194. writeByte( x >>> 24 );
  195. writeByte( (x >> 16) & 0xFF );
  196. writeByte( (x >> 8) & 0xFF );
  197. writeByte( x & 0xFF );
  198. } else {
  199. writeByte( x & 0xFF );
  200. writeByte( (x >> 8) & 0xFF );
  201. writeByte( (x >> 16) & 0xFF );
  202. writeByte( x >>> 24 );
  203. }
  204. }
  205. /**
  206. Inform that we are about to write at least `nbytes` bytes.
  207. The underlying implementation can allocate proper working space depending
  208. on this information, or simply ignore it. This is not a mandatory call
  209. but a tip and is only used in some specific cases.
  210. **/
  211. public function prepare( nbytes : Int ) {
  212. }
  213. /**
  214. Read all available data from `i` and write it.
  215. The `bufsize` optional argument specifies the size of chunks by
  216. which data is read and written. Its default value is 4096.
  217. **/
  218. public function writeInput( i : Input, ?bufsize : Int ) {
  219. if( bufsize == null )
  220. bufsize = 4096;
  221. var buf = Bytes.alloc(bufsize);
  222. try {
  223. while( true ) {
  224. var len = i.readBytes(buf,0,bufsize);
  225. if( len == 0 )
  226. throw Error.Blocked;
  227. var p = 0;
  228. while( len > 0 ) {
  229. var k = writeBytes(buf,p,len);
  230. if( k == 0 )
  231. throw Error.Blocked;
  232. p += k;
  233. len -= k;
  234. }
  235. }
  236. } catch( e : Eof ) {
  237. }
  238. }
  239. /**
  240. Write `s` string.
  241. **/
  242. public function writeString( s : String ) {
  243. #if neko
  244. var b = untyped new Bytes(s.length,s.__s);
  245. #else
  246. var b = Bytes.ofString(s);
  247. #end
  248. writeFullBytes(b,0,b.length);
  249. }
  250. #if neko
  251. static function __init__() untyped {
  252. Output.prototype.bigEndian = false;
  253. }
  254. #end
  255. }