UNPKG

madeline-ton

Version:

Pure JS client-side implementation of the Telegram TON blockchain protocol

198 lines (164 loc) 5.21 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _stream = _interopRequireDefault(require("../TL/stream")); var _tools = require("../tools"); var BitStream = /*#__PURE__*/ function () { /** * Construct stream * @param {ArrayBuffer} aBuf Buffer */ function BitStream(aBuf) { (0, _classCallCheck2["default"])(this, BitStream); this.pos = 0; // In bits this.aBuf = aBuf || new ArrayBuffer(128); // Max length for cells this.bBuf = new Uint8Array(this.aBuf); this.refs = []; this.refIdx = 0; } /** * Write bits to stream * @param {number|Uint8Array} n Number to write * @param {number} length Bit length of field */ (0, _createClass2["default"])(BitStream, [{ key: "writeBits", value: function writeBits(n, length) { var byteLength = Math.ceil(length / 8); if (!(n instanceof Uint8Array)) { if (!_stream["default"].bigEndian) { n = _stream["default"].switcheroo(n); } n = new Uint8Array(new Uint32Array([n]).buffer).subarray(-byteLength); } var inputShift = 8 - (length & 7); length += inputShift; for (var bitPos = inputShift; bitPos < length; bitPos++, this.pos++) { //console.log(n, bitPos, bitPos >> 3, bitPos & 7, n[bitPos >> 3], (n[bitPos >> 3] >> (8 - ((bitPos & 7) + 1))) & 1) this.bBuf[this.pos >> 3] |= (n[bitPos >> 3] >> 8 - ((bitPos & 7) + 1) & 1) << 8 - ((this.pos & 7) + 1); } return this; } /** * Read bits from stream * @param {number} length Number of bits to read * @param {bool} toInt Whether to convert result to a javascript integer if length <= 32 * @returns {Uint8Array} Bitstring */ }, { key: "readBits", value: function readBits(length) { var toInt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; var result = new Uint8Array(Math.ceil(length / 8)); var inputShift = (0, _tools.posMod)(-(length & 7), 8); length += inputShift; for (var bitPos = inputShift; bitPos < length; bitPos++, this.pos++) { //console.log(this.bBuf, bitPos, bitPos >> 3, bitPos & 7, this.bBuf[bitPos >> 3], (this.bBuf[bitPos >> 3] >> (8 - ((bitPos & 7) + 1))) & 1) result[bitPos >> 3] |= (this.bBuf[this.pos >> 3] >> 8 - ((this.pos & 7) + 1) & 1) << 8 - ((bitPos & 7) + 1); } if (toInt) { length = result.length; switch (length) { case 1: return result[0]; case 2: return new Uint16Array(_stream["default"].bigEndian ? result.buffer : result.reverse().buffer)[0]; case 3: var tmp = new Uint8Array(4); tmp.set(result, 1); result = tmp; case 4: return new Uint32Array(_stream["default"].bigEndian ? result.buffer : result.reverse().buffer)[0]; } } return result; } /** * Prepare buffer for serialization adding N more bits of free space * Shouldn't be used much, if at all * * @param {number} more bits to add * @returns Stream */ }, { key: "prepareLength", value: function prepareLength(more) { if (!more) return this; this.aBuf = transfer(this.aBuf, this.aBuf.byteLength + Math.ceil(more / 8)); this.bBuf = new Uint8Array(this.aBuf); return this; } /** * Push reference * @param {Uint8Array} buffer Serialized cell buffer * @returns BitStream */ }, { key: "pushRef", value: function pushRef(buffer) { if (this.refIdx === 4) { throw new Error("Trying to add too many references!"); } this.refs[this.refIdx++] = buffer; return this; } /** * Load reference, returning slice * @returns {BitStream} Slice */ }, { key: "loadRefSlice", value: function loadRefSlice() { return new BitStream(this.refs[this.refIdx++]); } /** * Load reference * @returns {Uint8Array} Cell */ }, { key: "loadRef", value: function loadRef() { return this.refs[this.refIdx++]; } /** * Preload reference * @returns {Uint8Array} Cell */ }, { key: "preloadRef", value: function preloadRef() { return this.refs[this.refIdx]; } /** * Skip reference */ }, { key: "skipRef", value: function skipRef() { if (this.refIdx === 4) { throw new Error("Trying to add too many references!"); } this.refIdx++; } /** * Skip bits * @param {number} length Bits to skip */ }, { key: "skip", value: function skip(length) { this.pos += length; } }]); return BitStream; }(); BitStream.bigEndian = _stream["default"].bigEndian; var _default = BitStream; exports["default"] = _default;