writable-tracking-buffer.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _jsbi = _interopRequireDefault(require("jsbi"));
  7. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8. const SHIFT_LEFT_32 = (1 << 16) * (1 << 16);
  9. const SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;
  10. const UNKNOWN_PLP_LEN = Buffer.from([0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
  11. const ZERO_LENGTH_BUFFER = Buffer.alloc(0);
  12. /**
  13. A Buffer-like class that tracks position.
  14. As values are written, the position advances by the size of the written data.
  15. When writing, automatically allocates new buffers if there's not enough space.
  16. */
  17. class WritableTrackingBuffer {
  18. constructor(initialSize, encoding, doubleSizeGrowth) {
  19. this.initialSize = initialSize;
  20. this.encoding = encoding || 'ucs2';
  21. this.doubleSizeGrowth = doubleSizeGrowth || false;
  22. this.buffer = Buffer.alloc(this.initialSize, 0);
  23. this.compositeBuffer = ZERO_LENGTH_BUFFER;
  24. this.position = 0;
  25. }
  26. get data() {
  27. this.newBuffer(0);
  28. return this.compositeBuffer;
  29. }
  30. copyFrom(buffer) {
  31. const length = buffer.length;
  32. this.makeRoomFor(length);
  33. buffer.copy(this.buffer, this.position);
  34. this.position += length;
  35. }
  36. makeRoomFor(requiredLength) {
  37. if (this.buffer.length - this.position < requiredLength) {
  38. if (this.doubleSizeGrowth) {
  39. let size = Math.max(128, this.buffer.length * 2);
  40. while (size < requiredLength) {
  41. size *= 2;
  42. }
  43. this.newBuffer(size);
  44. } else {
  45. this.newBuffer(requiredLength);
  46. }
  47. }
  48. }
  49. newBuffer(size) {
  50. const buffer = this.buffer.slice(0, this.position);
  51. this.compositeBuffer = Buffer.concat([this.compositeBuffer, buffer]);
  52. this.buffer = size === 0 ? ZERO_LENGTH_BUFFER : Buffer.alloc(size, 0);
  53. this.position = 0;
  54. }
  55. writeUInt8(value) {
  56. const length = 1;
  57. this.makeRoomFor(length);
  58. this.buffer.writeUInt8(value, this.position);
  59. this.position += length;
  60. }
  61. writeUInt16LE(value) {
  62. const length = 2;
  63. this.makeRoomFor(length);
  64. this.buffer.writeUInt16LE(value, this.position);
  65. this.position += length;
  66. }
  67. writeUShort(value) {
  68. this.writeUInt16LE(value);
  69. }
  70. writeUInt16BE(value) {
  71. const length = 2;
  72. this.makeRoomFor(length);
  73. this.buffer.writeUInt16BE(value, this.position);
  74. this.position += length;
  75. }
  76. writeUInt24LE(value) {
  77. const length = 3;
  78. this.makeRoomFor(length);
  79. this.buffer[this.position + 2] = value >>> 16 & 0xff;
  80. this.buffer[this.position + 1] = value >>> 8 & 0xff;
  81. this.buffer[this.position] = value & 0xff;
  82. this.position += length;
  83. }
  84. writeUInt32LE(value) {
  85. const length = 4;
  86. this.makeRoomFor(length);
  87. this.buffer.writeUInt32LE(value, this.position);
  88. this.position += length;
  89. }
  90. writeBigInt64LE(value) {
  91. this.writeBigU_Int64LE(value);
  92. }
  93. writeBigU_Int64LE(value) {
  94. this.makeRoomFor(8);
  95. let lo = _jsbi.default.toNumber(_jsbi.default.bitwiseAnd(value, _jsbi.default.BigInt(0xffffffff)));
  96. this.buffer[this.position++] = lo;
  97. lo = lo >> 8;
  98. this.buffer[this.position++] = lo;
  99. lo = lo >> 8;
  100. this.buffer[this.position++] = lo;
  101. lo = lo >> 8;
  102. this.buffer[this.position++] = lo;
  103. let hi = _jsbi.default.toNumber(_jsbi.default.bitwiseAnd(_jsbi.default.signedRightShift(value, _jsbi.default.BigInt(32)), _jsbi.default.BigInt(0xffffffff)));
  104. this.buffer[this.position++] = hi;
  105. hi = hi >> 8;
  106. this.buffer[this.position++] = hi;
  107. hi = hi >> 8;
  108. this.buffer[this.position++] = hi;
  109. hi = hi >> 8;
  110. this.buffer[this.position++] = hi;
  111. }
  112. writeInt64LE(value) {
  113. this.writeBigInt64LE(_jsbi.default.BigInt(value));
  114. }
  115. writeUInt32BE(value) {
  116. const length = 4;
  117. this.makeRoomFor(length);
  118. this.buffer.writeUInt32BE(value, this.position);
  119. this.position += length;
  120. }
  121. writeUInt40LE(value) {
  122. // inspired by https://github.com/dpw/node-buffer-more-ints
  123. this.writeInt32LE(value & -1);
  124. this.writeUInt8(Math.floor(value * SHIFT_RIGHT_32));
  125. }
  126. writeUInt64LE(value) {
  127. this.writeBigUInt64LE(_jsbi.default.BigInt(value));
  128. }
  129. writeBigUInt64LE(value) {
  130. this.writeBigU_Int64LE(value);
  131. }
  132. writeInt8(value) {
  133. const length = 1;
  134. this.makeRoomFor(length);
  135. this.buffer.writeInt8(value, this.position);
  136. this.position += length;
  137. }
  138. writeInt16LE(value) {
  139. const length = 2;
  140. this.makeRoomFor(length);
  141. this.buffer.writeInt16LE(value, this.position);
  142. this.position += length;
  143. }
  144. writeInt16BE(value) {
  145. const length = 2;
  146. this.makeRoomFor(length);
  147. this.buffer.writeInt16BE(value, this.position);
  148. this.position += length;
  149. }
  150. writeInt32LE(value) {
  151. const length = 4;
  152. this.makeRoomFor(length);
  153. this.buffer.writeInt32LE(value, this.position);
  154. this.position += length;
  155. }
  156. writeInt32BE(value) {
  157. const length = 4;
  158. this.makeRoomFor(length);
  159. this.buffer.writeInt32BE(value, this.position);
  160. this.position += length;
  161. }
  162. writeFloatLE(value) {
  163. const length = 4;
  164. this.makeRoomFor(length);
  165. this.buffer.writeFloatLE(value, this.position);
  166. this.position += length;
  167. }
  168. writeDoubleLE(value) {
  169. const length = 8;
  170. this.makeRoomFor(length);
  171. this.buffer.writeDoubleLE(value, this.position);
  172. this.position += length;
  173. }
  174. writeString(value, encoding) {
  175. if (encoding == null) {
  176. encoding = this.encoding;
  177. }
  178. const length = Buffer.byteLength(value, encoding);
  179. this.makeRoomFor(length); // $FlowFixMe https://github.com/facebook/flow/pull/5398
  180. this.buffer.write(value, this.position, encoding);
  181. this.position += length;
  182. }
  183. writeBVarchar(value, encoding) {
  184. this.writeUInt8(value.length);
  185. this.writeString(value, encoding);
  186. }
  187. writeUsVarchar(value, encoding) {
  188. this.writeUInt16LE(value.length);
  189. this.writeString(value, encoding);
  190. } // TODO: Figure out what types are passed in other than `Buffer`
  191. writeUsVarbyte(value, encoding) {
  192. if (encoding == null) {
  193. encoding = this.encoding;
  194. }
  195. let length;
  196. if (value instanceof Buffer) {
  197. length = value.length;
  198. } else {
  199. value = value.toString();
  200. length = Buffer.byteLength(value, encoding);
  201. }
  202. this.writeUInt16LE(length);
  203. if (value instanceof Buffer) {
  204. this.writeBuffer(value);
  205. } else {
  206. this.makeRoomFor(length); // $FlowFixMe https://github.com/facebook/flow/pull/5398
  207. this.buffer.write(value, this.position, encoding);
  208. this.position += length;
  209. }
  210. }
  211. writePLPBody(value, encoding) {
  212. if (encoding == null) {
  213. encoding = this.encoding;
  214. }
  215. let length;
  216. if (value instanceof Buffer) {
  217. length = value.length;
  218. } else {
  219. value = value.toString();
  220. length = Buffer.byteLength(value, encoding);
  221. } // Length of all chunks.
  222. // this.writeUInt64LE(length);
  223. // unknown seems to work better here - might revisit later.
  224. this.writeBuffer(UNKNOWN_PLP_LEN); // In the UNKNOWN_PLP_LEN case, the data is represented as a series of zero or more chunks.
  225. if (length > 0) {
  226. // One chunk.
  227. this.writeUInt32LE(length);
  228. if (value instanceof Buffer) {
  229. this.writeBuffer(value);
  230. } else {
  231. this.makeRoomFor(length);
  232. this.buffer.write(value, this.position, encoding);
  233. this.position += length;
  234. }
  235. } // PLP_TERMINATOR (no more chunks).
  236. this.writeUInt32LE(0);
  237. }
  238. writeBuffer(value) {
  239. const length = value.length;
  240. this.makeRoomFor(length);
  241. value.copy(this.buffer, this.position);
  242. this.position += length;
  243. }
  244. writeMoney(value) {
  245. this.writeInt32LE(Math.floor(value * SHIFT_RIGHT_32));
  246. this.writeInt32LE(value & -1);
  247. }
  248. }
  249. var _default = WritableTrackingBuffer;
  250. exports.default = _default;
  251. module.exports = WritableTrackingBuffer;