UNPKG

token-types

Version:

Common token types for decoding and encoding numeric and string values

418 lines (417 loc) 10.5 kB
import * as ieee754 from 'ieee754'; // Primitive types function dv(array) { return new DataView(array.buffer, array.byteOffset); } /** * 8-bit unsigned integer */ export const UINT8 = { len: 1, get(array, offset) { return dv(array).getUint8(offset); }, put(array, offset, value) { dv(array).setUint8(offset, value); return offset + 1; } }; /** * 16-bit unsigned integer, Little Endian byte order */ export const UINT16_LE = { len: 2, get(array, offset) { return dv(array).getUint16(offset, true); }, put(array, offset, value) { dv(array).setUint16(offset, value, true); return offset + 2; } }; /** * 16-bit unsigned integer, Big Endian byte order */ export const UINT16_BE = { len: 2, get(array, offset) { return dv(array).getUint16(offset); }, put(array, offset, value) { dv(array).setUint16(offset, value); return offset + 2; } }; /** * 24-bit unsigned integer, Little Endian byte order */ export const UINT24_LE = { len: 3, get(array, offset) { const dataView = dv(array); return dataView.getUint8(offset) + (dataView.getUint16(offset + 1, true) << 8); }, put(array, offset, value) { const dataView = dv(array); dataView.setUint8(offset, value & 0xff); dataView.setUint16(offset + 1, value >> 8, true); return offset + 3; } }; /** * 24-bit unsigned integer, Big Endian byte order */ export const UINT24_BE = { len: 3, get(array, offset) { const dataView = dv(array); return (dataView.getUint16(offset) << 8) + dataView.getUint8(offset + 2); }, put(array, offset, value) { const dataView = dv(array); dataView.setUint16(offset, value >> 8); dataView.setUint8(offset + 2, value & 0xff); return offset + 3; } }; /** * 32-bit unsigned integer, Little Endian byte order */ export const UINT32_LE = { len: 4, get(array, offset) { return dv(array).getUint32(offset, true); }, put(array, offset, value) { dv(array).setUint32(offset, value, true); return offset + 4; } }; /** * 32-bit unsigned integer, Big Endian byte order */ export const UINT32_BE = { len: 4, get(array, offset) { return dv(array).getUint32(offset); }, put(array, offset, value) { dv(array).setUint32(offset, value); return offset + 4; } }; /** * 8-bit signed integer */ export const INT8 = { len: 1, get(array, offset) { return dv(array).getInt8(offset); }, put(array, offset, value) { dv(array).setInt8(offset, value); return offset + 1; } }; /** * 16-bit signed integer, Big Endian byte order */ export const INT16_BE = { len: 2, get(array, offset) { return dv(array).getInt16(offset); }, put(array, offset, value) { dv(array).setInt16(offset, value); return offset + 2; } }; /** * 16-bit signed integer, Little Endian byte order */ export const INT16_LE = { len: 2, get(array, offset) { return dv(array).getInt16(offset, true); }, put(array, offset, value) { dv(array).setInt16(offset, value, true); return offset + 2; } }; /** * 24-bit signed integer, Little Endian byte order */ export const INT24_LE = { len: 3, get(array, offset) { const unsigned = UINT24_LE.get(array, offset); return unsigned > 0x7fffff ? unsigned - 0x1000000 : unsigned; }, put(array, offset, value) { const dataView = dv(array); dataView.setUint8(offset, value & 0xff); dataView.setUint16(offset + 1, value >> 8, true); return offset + 3; } }; /** * 24-bit signed integer, Big Endian byte order */ export const INT24_BE = { len: 3, get(array, offset) { const unsigned = UINT24_BE.get(array, offset); return unsigned > 0x7fffff ? unsigned - 0x1000000 : unsigned; }, put(array, offset, value) { const dataView = dv(array); dataView.setUint16(offset, value >> 8); dataView.setUint8(offset + 2, value & 0xff); return offset + 3; } }; /** * 32-bit signed integer, Big Endian byte order */ export const INT32_BE = { len: 4, get(array, offset) { return dv(array).getInt32(offset); }, put(array, offset, value) { dv(array).setInt32(offset, value); return offset + 4; } }; /** * 32-bit signed integer, Big Endian byte order */ export const INT32_LE = { len: 4, get(array, offset) { return dv(array).getInt32(offset, true); }, put(array, offset, value) { dv(array).setInt32(offset, value, true); return offset + 4; } }; /** * 64-bit unsigned integer, Little Endian byte order */ export const UINT64_LE = { len: 8, get(array, offset) { return dv(array).getBigUint64(offset, true); }, put(array, offset, value) { dv(array).setBigUint64(offset, value, true); return offset + 8; } }; /** * 64-bit signed integer, Little Endian byte order */ export const INT64_LE = { len: 8, get(array, offset) { return dv(array).getBigInt64(offset, true); }, put(array, offset, value) { dv(array).setBigInt64(offset, value, true); return offset + 8; } }; /** * 64-bit unsigned integer, Big Endian byte order */ export const UINT64_BE = { len: 8, get(array, offset) { return dv(array).getBigUint64(offset); }, put(array, offset, value) { dv(array).setBigUint64(offset, value); return offset + 8; } }; /** * 64-bit signed integer, Big Endian byte order */ export const INT64_BE = { len: 8, get(array, offset) { return dv(array).getBigInt64(offset); }, put(array, offset, value) { dv(array).setBigInt64(offset, value); return offset + 8; } }; /** * IEEE 754 16-bit (half precision) float, big endian */ export const Float16_BE = { len: 2, get(dataView, offset) { return ieee754.read(dataView, offset, false, 10, this.len); }, put(dataView, offset, value) { ieee754.write(dataView, value, offset, false, 10, this.len); return offset + this.len; } }; /** * IEEE 754 16-bit (half precision) float, little endian */ export const Float16_LE = { len: 2, get(array, offset) { return ieee754.read(array, offset, true, 10, this.len); }, put(array, offset, value) { ieee754.write(array, value, offset, true, 10, this.len); return offset + this.len; } }; /** * IEEE 754 32-bit (single precision) float, big endian */ export const Float32_BE = { len: 4, get(array, offset) { return dv(array).getFloat32(offset); }, put(array, offset, value) { dv(array).setFloat32(offset, value); return offset + 4; } }; /** * IEEE 754 32-bit (single precision) float, little endian */ export const Float32_LE = { len: 4, get(array, offset) { return dv(array).getFloat32(offset, true); }, put(array, offset, value) { dv(array).setFloat32(offset, value, true); return offset + 4; } }; /** * IEEE 754 64-bit (double precision) float, big endian */ export const Float64_BE = { len: 8, get(array, offset) { return dv(array).getFloat64(offset); }, put(array, offset, value) { dv(array).setFloat64(offset, value); return offset + 8; } }; /** * IEEE 754 64-bit (double precision) float, little endian */ export const Float64_LE = { len: 8, get(array, offset) { return dv(array).getFloat64(offset, true); }, put(array, offset, value) { dv(array).setFloat64(offset, value, true); return offset + 8; } }; /** * IEEE 754 80-bit (extended precision) float, big endian */ export const Float80_BE = { len: 10, get(array, offset) { return ieee754.read(array, offset, false, 63, this.len); }, put(array, offset, value) { ieee754.write(array, value, offset, false, 63, this.len); return offset + this.len; } }; /** * IEEE 754 80-bit (extended precision) float, little endian */ export const Float80_LE = { len: 10, get(array, offset) { return ieee754.read(array, offset, true, 63, this.len); }, put(array, offset, value) { ieee754.write(array, value, offset, true, 63, this.len); return offset + this.len; } }; /** * Ignore a given number of bytes */ export class IgnoreType { /** * @param len number of bytes to ignore */ constructor(len) { this.len = len; } // ToDo: don't read, but skip data get(_array, _off) { } } export class Uint8ArrayType { constructor(len) { this.len = len; } get(array, offset) { return array.subarray(offset, offset + this.len); } } /** * Consume a fixed number of bytes from the stream and return a string with a specified encoding. * Supports all encodings supported by TextDecoder, plus 'windows-1252'. */ export class StringType { constructor(len, encoding) { this.len = len; if (encoding && encoding.toLowerCase() === 'windows-1252') { this.decoder = StringType.decodeWindows1252; } else { const textDecoder = new TextDecoder(encoding); this.decoder = (bytes) => textDecoder.decode(bytes); } } get(data, offset = 0) { const bytes = data.subarray(offset, offset + this.len); return this.decoder(bytes); } static decodeWindows1252(bytes) { let result = ''; for (let i = 0; i < bytes.length; i++) { const byte = bytes[i]; result += byte < 0x80 || byte >= 0xA0 ? String.fromCharCode(byte) : StringType.win1252Map[byte - 0x80]; } return result; } } StringType.win1252Map = '\u20AC\u0081\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\u0160\u2039\u0152\u008D\u017D\u008F\u0090\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u02DC\u2122\u0161\u203A\u0153\u009D\u017E\u0178'; /** * ANSI Latin 1 String using Windows-1252 (Code Page 1252) * Windows-1252 is a superset of ISO 8859-1 / Latin-1. */ export class AnsiStringType extends StringType { constructor(len) { super(len, 'windows-1252'); } }