asn1-ts
Version:
ASN.1 encoding and decoding, including BER, CER, and DER.
68 lines (67 loc) • 3.13 kB
JavaScript
import convertBytesToText from "../../../utils/convertBytesToText.mjs";
import * as errors from "../../../errors.mjs";
import { DURATION_EQUIVALENT } from "../../../types/index.mjs";
import { durationRegex } from "../../../values.mjs";
export default function decodeDuration(bytes) {
const str = convertBytesToText(bytes);
if (str.indexOf(",") !== -1) {
throw new errors.ASN1Error("Comma prohibited in DURATION when using the Distinguished or Canonical Encoding Rules.");
}
if (str.indexOf("W") === (str.length - 1)) {
const weekString = str.slice(0, -1);
const indexOfDecimalSeparator = weekString.indexOf(".");
const weeks = indexOfDecimalSeparator !== -1
? parseInt(weekString.slice(0, indexOfDecimalSeparator), 10)
: parseInt(weekString, 10);
if (Number.isNaN(weeks)) {
throw new errors.ASN1Error(`Could not decode a real number of weeks from DURATION ${str}.`);
}
let fractional_part = undefined;
if (indexOfDecimalSeparator !== -1) {
const fractionString = weekString.slice(indexOfDecimalSeparator + 1);
const fractionValue = parseInt(fractionString, 10);
if (Number.isNaN(fractionValue)) {
throw new errors.ASN1Error(`Could not decode a fractional number of weeks from DURATION ${str}.`);
}
fractional_part = {
number_of_digits: fractionString.length,
fractional_value: fractionValue,
};
}
return new DURATION_EQUIVALENT(undefined, undefined, weeks, undefined, undefined, undefined, undefined, fractional_part);
}
const match = durationRegex.exec(str);
if (!match) {
throw new errors.ASN1Error(`Malformed DURATION ${str}.`);
}
let fractional_part = undefined;
[
match[1],
match[2],
match[3],
match[4],
match[5],
match[6],
].forEach((component) => {
if (!component) {
return;
}
if (fractional_part) {
throw new errors.ASN1Error(`No smaller components permitted after fractional component in DURATION ${str}.`);
}
const indexOfFractionalSeparator = component.indexOf(".");
if (indexOfFractionalSeparator !== -1) {
fractional_part = {
number_of_digits: (component.length - 1 - indexOfFractionalSeparator),
fractional_value: Number.parseInt(component.slice(indexOfFractionalSeparator + 1), 10),
};
}
});
const years = match[1] ? Number.parseInt(match[1], 10) : undefined;
const months = match[2] ? Number.parseInt(match[2], 10) : undefined;
const days = match[3] ? Number.parseInt(match[3], 10) : undefined;
const hours = match[4] ? Number.parseInt(match[4], 10) : undefined;
const minutes = match[5] ? Number.parseInt(match[5], 10) : undefined;
const seconds = match[6] ? Number.parseInt(match[6], 10) : undefined;
return new DURATION_EQUIVALENT(years, months, undefined, days, hours, minutes, seconds, fractional_part);
}