/* * bytestream.js * * Provides a writer for bytes. * * Licensed under the MIT License * * Copyright(c) 2011 Google Inc. * Copyright(c) 2011 antimatter15 */ var bitjs = bitjs || {}; bitjs.io = bitjs.io || {}; /** * A write-only Byte buffer which uses a Uint8 Typed Array as a backing store. */ bitjs.io.ByteBuffer = class { /** * @param {number} numBytes The number of bytes to allocate. */ constructor(numBytes) { if (typeof numBytes != typeof 1 || numBytes <= 0) { throw "Error! ByteBuffer initialized with '" + numBytes + "'"; } this.data = new Uint8Array(numBytes); this.ptr = 0; } /** * @param {number} b The byte to insert. */ insertByte(b) { // TODO: throw if byte is invalid? this.data[this.ptr++] = b; } /** * @param {Array.|Uint8Array|Int8Array} bytes The bytes to insert. */ insertBytes(bytes) { // TODO: throw if bytes is invalid? this.data.set(bytes, this.ptr); this.ptr += bytes.length; } /** * Writes an unsigned number into the next n bytes. If the number is too large * to fit into n bytes or is negative, an error is thrown. * @param {number} num The unsigned number to write. * @param {number} numBytes The number of bytes to write the number into. */ writeNumber(num, numBytes) { if (numBytes < 1 || !numBytes) { throw 'Trying to write into too few bytes: ' + numBytes; } if (num < 0) { throw 'Trying to write a negative number (' + num + ') as an unsigned number to an ArrayBuffer'; } if (num > (Math.pow(2, numBytes * 8) - 1)) { throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; } // Roll 8-bits at a time into an array of bytes. const bytes = []; while (numBytes-- > 0) { const eightBits = num & 255; bytes.push(eightBits); num >>= 8; } this.insertBytes(bytes); } /** * Writes a signed number into the next n bytes. If the number is too large * to fit into n bytes, an error is thrown. * @param {number} num The signed number to write. * @param {number} numBytes The number of bytes to write the number into. */ writeSignedNumber(num, numBytes) { if (numBytes < 1) { throw 'Trying to write into too few bytes: ' + numBytes; } const HALF = Math.pow(2, (numBytes * 8) - 1); if (num >= HALF || num < -HALF) { throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; } // Roll 8-bits at a time into an array of bytes. const bytes = []; while (numBytes-- > 0) { const eightBits = num & 255; bytes.push(eightBits); num >>= 8; } this.insertBytes(bytes); } /** * @param {string} str The ASCII string to write. */ writeASCIIString(str) { for (let i = 0; i < str.length; ++i) { const curByte = str.charCodeAt(i); if (curByte < 0 || curByte > 255) { throw 'Trying to write a non-ASCII string!'; } this.insertByte(curByte); } }; }