UNPKG

ebml-stream

Version:
154 lines (153 loc) 4.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class Tools { static readVint(buffer, start = 0) { const length = 8 - Math.floor(Math.log2(buffer[start])); if (length > 8) { const number = Tools.readHexString(buffer, start, start + length); throw new Error(`Unrepresentable length: ${length} ${number}`); } if (isNaN(length) || start + length > buffer.length) { return null; } if (length === 8 && buffer[start + 1] >= 0x20 && buffer.subarray(start + 2, start + 8).some(i => i > 0x00)) { return { length: 8, value: -1 }; } let value = buffer[start] & ((1 << (8 - length)) - 1); for (let i = 1; i < length; i += 1) { value *= Math.pow(2, 8); value += buffer[start + i]; } if (value === (Math.pow(2, (length * 7)) - 1)) { value = -1; } return { length, value, }; } static writeVint(value, desiredLength) { if (value < 0 || value > (Math.pow(2, 53))) { throw new Error(`Unrepresentable value: ${value}`); } let length = desiredLength; if (!length) { for (length = 1; length <= 8; length += 1) { if (value < Math.pow(2, (7 * length)) - 1) { break; } } } const buffer = Buffer.alloc(length); let val = value; for (let i = 1; i <= length; i += 1) { const b = val & 0xff; buffer[length - i] = b; val -= b; val /= Math.pow(2, 8); } buffer[0] |= 1 << (8 - length); return buffer; } static padStart(val) { if (val.length == 0) { return '00'; } if (val.length == 1) { return '0' + val; } return val; } static readHexString(buff, start = 0, end = buff.byteLength) { return Array.from(buff.subarray(start, end)) .map(q => Number(q).toString(16)) .reduce((acc, current) => `${acc}${this.padStart(current)}`, ''); } static readUtf8(buff) { try { return Buffer.from(buff).toString('utf8'); } catch (exception) { return null; } } static readUnsigned(buff) { const b = new DataView(buff.buffer, buff.byteOffset, buff.byteLength); switch (buff.byteLength) { case 1: return b.getUint8(0); case 2: return b.getUint16(0); case 4: return b.getUint32(0); default: break; } if (buff.byteLength <= 6) { return buff.reduce((acc, current) => acc * 256 + current, 0); } var hex = Tools.readHexString(buff, 0, buff.byteLength); var num = parseInt(hex, 16); if (num <= Math.pow(256, 6)) { return num; } return hex; } static writeUnsigned(num) { if (typeof num === 'string') { return Buffer.from(num, 'hex'); } else { var buf = Buffer.alloc(6); buf.fill(0); buf.writeUIntBE(num, 0, 6); let firstValueIndex = buf.findIndex(b => b !== 0); if (firstValueIndex === -1) { firstValueIndex = buf.length - 1; } let ret = buf.slice(firstValueIndex); return ret; } } static readSigned(buff) { const b = new DataView(buff.buffer, buff.byteOffset, buff.byteLength); switch (buff.byteLength) { case 1: return b.getInt8(0); case 2: return b.getInt16(0); case 4: return b.getInt32(0); default: return NaN; } } static writeSigned(num) { var buf = Buffer.alloc(8); buf.writeInt32BE(num, 0); return buf; } static readFloat(buff) { const b = new DataView(buff.buffer, buff.byteOffset, buff.byteLength); switch (buff.byteLength) { case 4: return b.getFloat32(0); case 8: return b.getFloat64(0); default: return NaN; } } static writeFloat(num) { let buf = Buffer.alloc(8); let written = buf.writeFloatBE(num, 0); if (written <= 4) { buf = buf.slice(0, 4); } return buf; } } exports.Tools = Tools;