UNPKG

asn1-ts

Version:

ASN.1 encoding and decoding, including BER, CER, and DER.

44 lines (43 loc) 1.9 kB
import dissectFloat from "./dissectFloat.mjs"; import encodeUnsignedBigEndianInteger from "./encodeUnsignedBigEndianInteger.mjs"; import encodeSignedBigEndianInteger from "./encodeSignedBigEndianInteger.mjs"; import { ASN1SpecialRealValue } from "../values.mjs"; import * as errors from "../errors.mjs"; export default function encodeX690BinaryRealNumber(value) { if (value === 0.0) { return new Uint8Array(0); } else if (Number.isNaN(value)) { return new Uint8Array([ASN1SpecialRealValue.notANumber]); } else if (value === -0.0) { return new Uint8Array([ASN1SpecialRealValue.minusZero]); } else if (value === Infinity) { return new Uint8Array([ASN1SpecialRealValue.plusInfinity]); } else if (value === -Infinity) { return new Uint8Array([ASN1SpecialRealValue.minusInfinity]); } const floatComponents = dissectFloat(value); while (floatComponents.mantissa !== 0 && (floatComponents.mantissa % 2) === 0) { floatComponents.mantissa = floatComponents.mantissa >>> 1; floatComponents.exponent++; } if (floatComponents.exponent <= -1020) { throw new errors.ASN1OverflowError(`REAL number ${value} (having exponent ${floatComponents.exponent}) ` + "is too precise to encode."); } const singleByteExponent = ((floatComponents.exponent <= 127) && (floatComponents.exponent >= -128)); const firstByte = (128 | (value >= 0 ? 0 : 64) | (singleByteExponent ? 0 : 1)); const exponentBytes = encodeSignedBigEndianInteger(floatComponents.exponent); const mantissaBytes = encodeUnsignedBigEndianInteger(floatComponents.mantissa); const ret = new Uint8Array(1 + exponentBytes.length + mantissaBytes.length); ret[0] = firstByte; ret.set(exponentBytes, 1); ret.set(mantissaBytes, (1 + exponentBytes.length)); return ret; }