'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var token = require('./token.js'); var common = require('./common.js'); var _0uint = require('./0uint.js'); const MINOR_FALSE = 20; const MINOR_TRUE = 21; const MINOR_NULL = 22; const MINOR_UNDEFINED = 23; function decodeUndefined(_data, _pos, _minor, options) { if (options.allowUndefined === false) { throw new Error(`${ common.decodeErrPrefix } undefined values are not supported`); } else if (options.coerceUndefinedToNull === true) { return new token.Token(token.Type.null, null, 1); } return new token.Token(token.Type.undefined, undefined, 1); } function decodeBreak(_data, _pos, _minor, options) { if (options.allowIndefinite === false) { throw new Error(`${ common.decodeErrPrefix } indefinite length items not allowed`); } return new token.Token(token.Type.break, undefined, 1); } function createToken(value, bytes, options) { if (options) { if (options.allowNaN === false && Number.isNaN(value)) { throw new Error(`${ common.decodeErrPrefix } NaN values are not supported`); } if (options.allowInfinity === false && (value === Infinity || value === -Infinity)) { throw new Error(`${ common.decodeErrPrefix } Infinity values are not supported`); } } return new token.Token(token.Type.float, value, bytes); } function decodeFloat16(data, pos, _minor, options) { return createToken(readFloat16(data, pos + 1), 3, options); } function decodeFloat32(data, pos, _minor, options) { return createToken(readFloat32(data, pos + 1), 5, options); } function decodeFloat64(data, pos, _minor, options) { return createToken(readFloat64(data, pos + 1), 9, options); } function encodeFloat(buf, token$1, options) { const float = token$1.value; if (float === false) { buf.push([token.Type.float.majorEncoded | MINOR_FALSE]); } else if (float === true) { buf.push([token.Type.float.majorEncoded | MINOR_TRUE]); } else if (float === null) { buf.push([token.Type.float.majorEncoded | MINOR_NULL]); } else if (float === undefined) { buf.push([token.Type.float.majorEncoded | MINOR_UNDEFINED]); } else { let decoded; let success = false; if (!options || options.float64 !== true) { encodeFloat16(float); decoded = readFloat16(ui8a, 1); if (float === decoded || Number.isNaN(float)) { ui8a[0] = 249; buf.push(ui8a.slice(0, 3)); success = true; } else { encodeFloat32(float); decoded = readFloat32(ui8a, 1); if (float === decoded) { ui8a[0] = 250; buf.push(ui8a.slice(0, 5)); success = true; } } } if (!success) { encodeFloat64(float); decoded = readFloat64(ui8a, 1); ui8a[0] = 251; buf.push(ui8a.slice(0, 9)); } } } encodeFloat.encodedSize = function encodedSize(token, options) { const float = token.value; if (float === false || float === true || float === null || float === undefined) { return 1; } if (!options || options.float64 !== true) { encodeFloat16(float); let decoded = readFloat16(ui8a, 1); if (float === decoded || Number.isNaN(float)) { return 3; } encodeFloat32(float); decoded = readFloat32(ui8a, 1); if (float === decoded) { return 5; } } return 9; }; const buffer = new ArrayBuffer(9); const dataView = new DataView(buffer, 1); const ui8a = new Uint8Array(buffer, 0); function encodeFloat16(inp) { if (inp === Infinity) { dataView.setUint16(0, 31744, false); } else if (inp === -Infinity) { dataView.setUint16(0, 64512, false); } else if (Number.isNaN(inp)) { dataView.setUint16(0, 32256, false); } else { dataView.setFloat32(0, inp); const valu32 = dataView.getUint32(0); const exponent = (valu32 & 2139095040) >> 23; const mantissa = valu32 & 8388607; if (exponent === 255) { dataView.setUint16(0, 31744, false); } else if (exponent === 0) { dataView.setUint16(0, (inp & 2147483648) >> 16 | mantissa >> 13, false); } else { const logicalExponent = exponent - 127; if (logicalExponent < -24) { dataView.setUint16(0, 0); } else if (logicalExponent < -14) { dataView.setUint16(0, (valu32 & 2147483648) >> 16 | 1 << 24 + logicalExponent, false); } else { dataView.setUint16(0, (valu32 & 2147483648) >> 16 | logicalExponent + 15 << 10 | mantissa >> 13, false); } } } } function readFloat16(ui8a, pos) { if (ui8a.length - pos < 2) { throw new Error(`${ common.decodeErrPrefix } not enough data for float16`); } const half = (ui8a[pos] << 8) + ui8a[pos + 1]; if (half === 31744) { return Infinity; } if (half === 64512) { return -Infinity; } if (half === 32256) { return NaN; } const exp = half >> 10 & 31; const mant = half & 1023; let val; if (exp === 0) { val = mant * 2 ** -24; } else if (exp !== 31) { val = (mant + 1024) * 2 ** (exp - 25); } else { val = mant === 0 ? Infinity : NaN; } return half & 32768 ? -val : val; } function encodeFloat32(inp) { dataView.setFloat32(0, inp, false); } function readFloat32(ui8a, pos) { if (ui8a.length - pos < 4) { throw new Error(`${ common.decodeErrPrefix } not enough data for float32`); } const offset = (ui8a.byteOffset || 0) + pos; return new DataView(ui8a.buffer, offset, 4).getFloat32(0, false); } function encodeFloat64(inp) { dataView.setFloat64(0, inp, false); } function readFloat64(ui8a, pos) { if (ui8a.length - pos < 8) { throw new Error(`${ common.decodeErrPrefix } not enough data for float64`); } const offset = (ui8a.byteOffset || 0) + pos; return new DataView(ui8a.buffer, offset, 8).getFloat64(0, false); } encodeFloat.compareTokens = _0uint.encodeUint.compareTokens; exports.decodeBreak = decodeBreak; exports.decodeFloat16 = decodeFloat16; exports.decodeFloat32 = decodeFloat32; exports.decodeFloat64 = decodeFloat64; exports.decodeUndefined = decodeUndefined; exports.encodeFloat = encodeFloat;