UNPKG

@syncfusion/ej2-pdf

Version:

Feature-rich JavaScript PDF library with built-in support for loading and manipulating PDF document.

1,000 lines (999 loc) 37.6 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); import { _PdfAbstractSyntaxElement } from './abstract-syntax'; import { _ConstructionType, _TagClassType, _UniversalType } from './enumerator'; import { _convertBytesToText } from './utils'; import { _handleExplicitConversion, _stringToBytes } from '../../../utils'; import { _PdfObjectIdentifier } from './identifier-mapping'; /** * Unique BER/DER encoding element used for encodings that require element uniqueness * and provides helpers for serialization and decoding of primitive and constructed values. * * @private */ var _PdfUniqueEncodingElement = /** @class */ (function (_super) { __extends(_PdfUniqueEncodingElement, _super); function _PdfUniqueEncodingElement(tagClass, construction, tagNumber, value) { if (tagClass === void 0) { tagClass = _TagClassType.universal; } if (construction === void 0) { construction = _ConstructionType.primitive; } if (tagNumber === void 0) { tagNumber = _UniversalType.endOfContent; } if (value === void 0) { value = undefined; } var _this = _super.call(this) || this; /** * Internal storage for this element's value; may be raw bytes or child elements. */ _this._value = new Uint8Array(0); _this._encode(value); _this._tagClass = tagClass; _this._construction = construction; _this._setTagNumber(tagNumber); return _this; } /** * Returns the raw value bytes for this element, handling explicit conversions * for primitive encodings and concatenating constructed content when necessary. * * @private * @returns {Uint8Array} The raw value bytes. */ _PdfUniqueEncodingElement.prototype._getValue = function () { if (Array.isArray(this._value)) { var encoded = this._encodeSequence(this._value); this._currentValueLength = encoded.length; return encoded; } var prim = _handleExplicitConversion(this._value); if (prim !== this._value) { this._value = prim; } this._currentValueLength = prim.length; return prim; }; /** * Sets the raw value bytes for this element and updates the cached length. * * @param {Uint8Array} v The value bytes to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setValue = function (v) { this._currentValueLength = v.length; this._value = v; }; /** * Decodes and returns the boolean value for this element. * * @private * @returns {boolean} The decoded boolean. */ _PdfUniqueEncodingElement.prototype._getBooleanValue = function () { if (this._construction !== _ConstructionType.primitive) { throw new Error('boolean cannot be constructed.'); } return this._decodeBoolean(this._getValue()); }; /** * Encodes and sets a boolean value for this element. * * @private * @param {boolean} value The boolean to set. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setBooleanValue = function (value) { this._setValue(this._encodeBoolean(value)); }; /** * Returns the bit string content for this element, concatenating parts if constructed. * * @private * @returns {Uint8ClampedArray} The bit string. */ _PdfUniqueEncodingElement.prototype._getBitString = function () { if (this._construction !== _ConstructionType.primitive) { throw new Error('Bit string cannot be constructed.'); } return this._decodeBitString(this._getValue()); }; /** * Encodes and sets a bit string value for this element. * * @private * @param {Uint8ClampedArray} value The bit string to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setBitString = function (value) { this._setValue(this._encodeBitString(value)); }; /** * Returns the octet string bytes for this element. * * @private * @returns {Uint8Array} The octet string bytes. */ _PdfUniqueEncodingElement.prototype._getOctetString = function () { if (this._construction !== _ConstructionType.primitive) { throw new Error('Octet string cannot be constructed.'); } return new Uint8Array(this._getValue()); }; /** * Sets the octet string value for this element. * * @private * @param {Uint8Array} value The octet string bytes to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setOctetString = function (value) { this._setValue(new Uint8Array(value)); }; /** * Returns the object descriptor string for this element. * * @private * @returns {string} The object descriptor. */ _PdfUniqueEncodingElement.prototype._getObjectDescriptor = function () { return this._decodeObjectDescriptor(this._getValue()); }; /** * Encodes and sets the object descriptor string for this element. * * @private * @param {string} value The descriptor to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setObjectDescriptor = function (value) { this._setValue(this._encodeObjectDescriptor(value)); }; /** * Returns the UTF-8 string value for this element. * * @private * @returns {string} The UTF-8 decoded string. */ _PdfUniqueEncodingElement.prototype._getUtf8String = function () { if (this._construction !== _ConstructionType.primitive) { throw new Error('Unicode text cannot be constructed.'); } return _convertBytesToText(this._getValue()); }; /** * Sets the UTF-8 string value for this element. * * @private * @param {string} value The UTF-8 string to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setUtf8String = function (value) { this._setValue(_stringToBytes(value)); }; /** * Returns the sequence child elements for this constructed element. * * @private * @returns {_PdfAbstractSyntaxElement[]} The sequence elements. */ _PdfUniqueEncodingElement.prototype._getSequence = function () { if (this._construction !== _ConstructionType.constructed) { throw new Error('Set or sequence cannot be primitively constructed.'); } if (Array.isArray(this._value)) { return this._value; } return this._decodeSequence(this._getValue()); }; /** * Sets the sequence child elements for this element and marks it constructed. * * @private * @param {_PdfAbstractSyntaxElement[]} value The sequence elements to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setSequence = function (value) { this._construct(value); this._construction = _ConstructionType.constructed; }; /** * Returns the elements for an abstract SET value after uniqueness validation. * * @private * @returns {_PdfAbstractSyntaxElement[]} The set elements. */ _PdfUniqueEncodingElement.prototype._getAbstractSetValue = function () { var ret = this._getSequence(); if (!this._isUniquelyTagged(ret)) { throw new Error('Duplicate tag in Set.'); } return ret; }; /** * Sets the elements for an abstract SET value. * * @private * @param {_PdfAbstractSyntaxElement[]} value The set elements to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setAbstractSetValue = function (value) { this._sortCanonically(value); this._setSequence(value); }; /** * Returns the elements when this is a `SEQUENCE OF`. * * @private * @returns {_PdfAbstractSyntaxElement[]} The sequence-of elements. */ _PdfUniqueEncodingElement.prototype._getSequenceOf = function () { if (this._construction !== _ConstructionType.constructed) { throw new Error('Set or sequence cannot be primitively constructed.'); } if (Array.isArray(this._value)) { return this._value; } return this._decodeSequence(this._getValue()); }; /** * Sets the elements when this is a `SEQUENCE OF` and marks constructed. * * @private * @param {_PdfAbstractSyntaxElement[]} value The elements to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setSequenceOf = function (value) { this._construct(value); this._construction = _ConstructionType.constructed; }; /** * Returns the elements when this is a `SET OF`. * * @private * @returns {_PdfAbstractSyntaxElement[]} The set-of elements. */ _PdfUniqueEncodingElement.prototype._getAbstractSetOf = function () { return this._getSequence(); }; /** * Sets the elements when this is a `SET OF`. * * @private * @param {_PdfAbstractSyntaxElement[]} value The elements to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setAbstractSetOf = function (value) { this._setSequence(value); }; _PdfUniqueEncodingElement.prototype._getNumericString = function () { if (this._construction !== _ConstructionType.primitive) { throw new Error('Numeric string cannot be constructed.'); } return this._decodeNumericString(this._getValue()); }; _PdfUniqueEncodingElement.prototype._setNumericString = function (value) { this._setValue(this._encodeNumericString(value)); }; /** * Returns the printable string value for this element. * * @private * @returns {string} The printable string. */ _PdfUniqueEncodingElement.prototype._getPrintableString = function () { if (this._construction !== _ConstructionType.primitive) { throw new Error('Printable ASCII string cannot be constructed.'); } return this._decodePrintableString(this._getValue()); }; /** * Sets the printable string value for this element. * * @private * @param {string} value The printable string to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setPrintableString = function (value) { this._setValue(this._encodePrintableString(value)); }; /** * Returns teleprinter (Teletex) text bytes for this element. * * @private * @returns {Uint8Array} The teleprinter bytes. */ _PdfUniqueEncodingElement.prototype._getTeleprinterText = function () { return this._serialize(); }; /** * Sets teleprinter text bytes for this element. * * @private * @param {Uint8Array} value The bytes to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setTeleprinterText = function (value) { this._setValue(new Uint8Array(value)); }; /** * Returns videotex information bytes for this element. * * @private * @returns {Uint8Array} The videotex bytes. */ _PdfUniqueEncodingElement.prototype._getVideoTextInformation = function () { return this._getOctetString(); }; /** * Sets videotex information bytes for this element. * * @private * @param {Uint8Array} value The bytes to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setVideoTextInformation = function (value) { this._setValue(new Uint8Array(value)); }; /** * Returns the IA5 (international alphabet) string for this element. * * @private * @returns {string} The IA5 string. */ _PdfUniqueEncodingElement.prototype._getInternationalAlphabetString = function () { if (this._construction !== _ConstructionType.primitive) { throw new Error('ASCII string cannot be constructed.'); } return _convertBytesToText(this._getValue()); }; /** * Sets the IA5 (international alphabet) string for this element. * * @private * @param {string} value The IA5 string to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setInternationalAlphabetString = function (value) { this._setValue(_stringToBytes(value)); }; /** * Returns the graphic string for this element. * * @private * @returns {string} The graphic string. */ _PdfUniqueEncodingElement.prototype._getGraphicString = function () { if (this._construction !== _ConstructionType.primitive) { throw new Error('Graphic string cannot be constructed.'); } return this._decodeGraphicString(this._getValue()); }; /** * Sets the graphic string value for this element. * * @private * @param {string} value The graphic string to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setGraphicString = function (value) { this._setValue(this._encodeGraphicString(value)); }; /** * Returns the visible string for this element. * * @private * @returns {string} The visible string. */ _PdfUniqueEncodingElement.prototype._getVisibleString = function () { return this._decodeVisibleString(this._getValue()); }; /** * Sets the visible string value for this element. * * @private * @param {string} value The visible string to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setVisibleString = function (value) { this._setValue(this._encodeVisibleString(value)); }; /** * Returns the universal (UTF-32) string for this element. * * @private * @returns {string} The universal string. */ _PdfUniqueEncodingElement.prototype._getUniversalString = function () { var values = this._getValue(); if (this._construction !== _ConstructionType.primitive) { throw new Error('Universal string cannot be constructed.'); } if (values.length % 4) { throw new Error('Universal string encoded on non-mulitple of four bytes.'); } var ret = ''; for (var i = 0; i < values.length; i += 4) { ret += String.fromCharCode((values[i + 0] << 24) + (values[i + 1] << 16) + (values[i + 2] << 8) + (values[i + 3] << 0)); } return ret; }; /** * Sets the universal (UTF-32) string for this element. * * @private * @param {string} value The universal string to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setUniversalString = function (value) { var buf = new Uint8Array(value.length << 2); for (var i = 0; i < value.length; i++) { buf[(i << 2)] = value.charCodeAt(i) >>> 24; buf[(i << 2) + 1] = value.charCodeAt(i) >>> 16; buf[(i << 2) + 2] = value.charCodeAt(i) >>> 8; buf[(i << 2) + 3] = value.charCodeAt(i); } this._setValue(buf); }; /** * Returns the BMP (UTF-16BE) string for this element. * * @private * @returns {string} The BMP string. */ _PdfUniqueEncodingElement.prototype._getBmpString = function () { var value = this._getValue(); if (this._construction !== _ConstructionType.primitive) { throw new Error('BMPString cannot be constructed.'); } if (value.length % 2 !== 0) { throw new Error('BMPString encoded on non-multiple of two bytes.'); } if (typeof TextDecoder !== 'undefined') { return new TextDecoder('utf-16be').decode(value); } var result = ''; for (var i = 0; i < value.length; i += 2) { var code = (value[i] << 8) | value[i + 1]; result += String.fromCharCode(code); } return result; }; /** * Sets the BMP (UTF-16BE) string for this element. * * @private * @param {string} value The BMP string to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setBmpString = function (value) { var buf = new Uint8Array(value.length << 1); for (var i = 0; i < value.length; i++) { var code = value.charCodeAt(i); buf[i << 1] = code >> 8; buf[(i << 1) + 1] = code & 0xff; } this._setValue(buf); }; /** * Constructs this element from provided child elements (internal helper). * * @private * @param {_PdfAbstractSyntaxElement[]} els The child elements to set. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._construct = function (els) { this._currentValueLength = undefined; this._value = els; }; /** * Encodes a JavaScript value into the appropriate ASN.1 encoding for this element. * * @private * @param {any} value The value to encode. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._encode = function (value) { switch (typeof value) { case ('undefined'): { this._setValue(new Uint8Array(0)); break; } case ('boolean'): { this._setTagNumber(_UniversalType.abstractSyntaxBoolean); this._setBooleanValue(value); break; } case ('number'): { if (Number.isInteger(value)) { this._setTagNumber(_UniversalType.integer); this._setInteger(value); } break; } case ('string'): { this._setTagNumber(_UniversalType.utf8String); this._setUtf8String(value); break; } case ('object'): { if (!value) { this._setTagNumber(_UniversalType.nullValue); this._setValue(new Uint8Array(0)); } else if (value instanceof Uint8Array) { this._setTagNumber(_UniversalType.octetString); this._setOctetString(value); } else if (value instanceof Uint8ClampedArray) { this._setTagNumber(_UniversalType.bitString); this._setBitString(value); } else if (value instanceof _PdfAbstractSyntaxElement) { this._construction = _ConstructionType.constructed; this._setSequence([value]); } else if (Array.isArray(value)) { this._construction = _ConstructionType.constructed; this._setTagNumber(_UniversalType.sequence); this._setSequence(value.map(function (sub) { var ret = new _PdfUniqueEncodingElement(); ret._encode(sub); return ret; })); } else if (value instanceof _PdfObjectIdentifier) { this._setTagNumber(_UniversalType.objectIdentifier); this._setObjectIdentifier(value); } else { throw new Error("Cannot encode value of type " + value.constructor.name + "."); } break; } default: { throw new Error("Cannot encode value of type " + typeof value + "."); } } }; /** * Wraps a set of basic encoding elements into a `_PdfUniqueEncodingElement` representing a SET. * * @private * @param {_PdfAbstractSyntaxElement[]} set The set elements. * @returns {_PdfUniqueEncodingElement} The constructed set element. */ _PdfUniqueEncodingElement.prototype._fromSet = function (set) { var ret = new _PdfUniqueEncodingElement(_TagClassType.universal, _ConstructionType.constructed, _UniversalType.abstractSyntaxSet); ret._setAbstractSetValue(set.filter(function (element) { return Boolean(element); })); return ret; }; /** * Wraps a set-of elements into a `_PdfUniqueEncodingElement` representing a SET OF. * * @private * @param {_PdfUniqueEncodingElement[]} set The set-of elements. * @returns {_PdfUniqueEncodingElement} The constructed set-of element. */ _PdfUniqueEncodingElement.prototype._fromSetOf = function (set) { var ret = new _PdfUniqueEncodingElement(_TagClassType.universal, _ConstructionType.constructed, _UniversalType.abstractSyntaxSet); ret._setAbstractSetOf(set.filter(function (element) { return Boolean(element); })); return ret; }; /** * Retrieves the single inner element for explicitly-encoded elements. * * @private * @returns {_PdfAbstractSyntaxElement} The inner element. */ _PdfUniqueEncodingElement.prototype._getInner = function () { if (this._construction !== _ConstructionType.constructed) { throw new Error('An explicitly-encoded element cannot be encoded using primitive construction.'); } if (Array.isArray(this._value)) { if (this._value.length !== 1) { throw new Error("An explicitly-encoding element contained " + this._value.length + " encoded elements."); } return this._value[0]; } var ret = new _PdfUniqueEncodingElement(); var readBytes = ret._fromBytes(this._value); if (readBytes !== this._value.length) { throw new Error('An explicitly-encoding element contained more than one single '); } return ret; }; /** * Sets a single inner element and marks this element as constructed. * * @private * @param {_PdfAbstractSyntaxElement} value The inner element to assign. * @returns {void} nothing. */ _PdfUniqueEncodingElement.prototype._setInner = function (value) { this._construction = _ConstructionType.constructed; this._value = [value]; }; /** * Decodes this element from the provided DER bytes and returns number of bytes consumed. * * @private * @param {Uint8Array} bytes The input bytes to decode. * @returns {number} The number of bytes consumed. */ _PdfUniqueEncodingElement.prototype._fromBytes = function (bytes) { if (bytes.length < 2) { throw new Error('Tried to decode a DER element that is less than two bytes.'); } var cursor = 0; switch (bytes[cursor] & 192) { case (0): this._tagClass = _TagClassType.universal; break; case (64): this._tagClass = _TagClassType.application; break; case (128): this._tagClass = _TagClassType.context; break; case (192): this._tagClass = _TagClassType.abstractSyntaxPrivate; break; } this._construction = ((bytes[cursor] & 32) ? _ConstructionType.constructed : _ConstructionType.primitive); this._setTagNumber((bytes[cursor] & 31)); cursor++; var tagNumber = this._getTagNumber(); if (tagNumber >= 31) { if (bytes[cursor] === 128) { throw new Error('Leading padding byte on long tag number encoding.'); } tagNumber = 0; var limit = (((bytes.length - 1) >= 4) ? 4 : (bytes.length - 1)); while (cursor < limit) { if (!(bytes[cursor++] & 128)) { break; } } if (bytes[cursor - 1] & 128) { if (limit === (bytes.length - 1)) { throw new Error('ASN1 tag number appears to have been truncated.'); } else { throw new Error('ASN1 tag number too large.'); } } for (var i = 1; i < cursor; i++) { tagNumber <<= 7; tagNumber |= (bytes[i] & 0x7F); } if (tagNumber < 31) { throw new Error('ASN1 tag number could have been encoded in short form.'); } } if ((bytes[cursor] & 128) === 128) { var numberOfLengthOctets = (bytes[cursor] & 0x7F); if (numberOfLengthOctets === 127) { // Reserved throw new Error('Length byte with undefined meaning encountered.'); } if (numberOfLengthOctets > 4) { throw new Error('Element length too long to decode to an integer.'); } if (cursor + numberOfLengthOctets >= bytes.length) { throw new Error('Element length bytes appear to have been truncated.'); } cursor++; var lengthNumberOctets = new Uint8Array(4); for (var i = numberOfLengthOctets; i > 0; i--) { lengthNumberOctets[(4 - i)] = bytes[(cursor + numberOfLengthOctets - i)]; } var length_1 = 0; lengthNumberOctets.forEach(function (octet) { length_1 <<= 8; length_1 += octet; }); if ((cursor + length_1) < cursor) { throw new Error('ASN1 element too large.'); } cursor += (numberOfLengthOctets); if ((cursor + length_1) > bytes.length) { throw new Error('ASN1 element truncated.'); } if (((length_1 <= 127 && length_1 >= -128) && numberOfLengthOctets > 1) || ((length_1 <= 32767 && length_1 >= -32768) && numberOfLengthOctets > 2) || ((length_1 <= 8388607 && length_1 >= -8388608) && numberOfLengthOctets > 3)) { throw new Error('DER-encoded long-form length encoded on more octets than necessary'); } this._setValue(bytes.slice(cursor, (cursor + length_1))); return (cursor + length_1); } else { var length_2 = (bytes[cursor++] & 0x7F); if ((cursor + length_2) > bytes.length) { throw new Error('ASN1 element was truncated.'); } this._setValue(bytes.slice(cursor, (cursor + length_2))); return (cursor + length_2); } }; /** * Produces the tag and length bytes for this element. * * @private * @returns {Uint8Array} The tag-and-length bytes. */ _PdfUniqueEncodingElement.prototype._tagAndLengthBytes = function () { var tagNumber = this._getTagNumber(); var first = ((this._tagClass & 0x03) << 6) | ((this._construction & 0x01) << 5); var tagBytes = []; if (tagNumber < 31) { tagBytes = [first | (tagNumber & 0x1f)]; } else { tagBytes = [first | 0x1f]; var tmp = []; var n = tagNumber; do { tmp.unshift(n & 0x7f); n >>>= 7; } while (n > 0); for (var i = 0; i < tmp.length; i++) { tagBytes.push(i < tmp.length - 1 ? (tmp[i] | 0x80) : tmp[i]); } } var lengthOctets = this._getLengthOctets(); var ret = new Uint8Array(tagBytes.length + lengthOctets.length); ret.set(tagBytes, 0); ret.set(lengthOctets, tagBytes.length); return ret; }; /** * Serializes this element into an array of buffers representing tag, length and value parts. * * @private * @returns {Uint8Array[]} Array of buffers. */ _PdfUniqueEncodingElement.prototype._toBuffers = function () { var head = this._tagAndLengthBytes(); var out = [head]; if (Array.isArray(this._value)) { for (var _i = 0, _a = this._value; _i < _a.length; _i++) { var el = _a[_i]; out.push.apply(out, el._toBuffers()); } } else { out.push(this._serialize()); } return out; }; /** * Serializes constructed or primitive content into a single byte buffer. * * @private * @returns {Uint8Array} The serialized value bytes. */ _PdfUniqueEncodingElement.prototype._serialize = function () { return new Uint8Array(this._getValue()); }; /** * Returns the length octets for the current value length. * * @private * @returns {number[]} The length octets. */ _PdfUniqueEncodingElement.prototype._getLengthOctets = function () { var length = this._valueLength(); if (length < 0x80) { return [length]; } var octets = []; var v = length; while (v > 0) { octets.unshift(v & 0xff); v >>>= 8; } return [0x80 | octets.length].concat(octets); }; /** * Returns the component elements when this element represents constructed content. * * @private * @returns {_PdfAbstractSyntaxElement[]} Component elements. */ _PdfUniqueEncodingElement.prototype._getComponents = function () { if (Array.isArray(this._value)) { return this._value; } var encodedElements = []; var i = 0; while (i < this._value.length) { var next = new _PdfUniqueEncodingElement(); i += next._fromBytes(this._getValue().subarray(i)); encodedElements.push(next); } return encodedElements; }; /** * Decodes an ASN.1 BIT STRING from bytes into a bit array. * * @private * @param {Uint8Array} value The bytes to decode. * @returns {Uint8ClampedArray} The decoded bit array. */ _PdfUniqueEncodingElement.prototype._decodeBitString = function (value) { if (value.length === 0) { throw new Error('ASN1 bit string cannot be encoded on zero bytes!'); } if (value.length === 1 && value[0] !== 0) { throw new Error('ASN1 bit string encoded with deceptive first byte!'); } if (value[0] > 7) { throw new Error('First byte of an ASN1 bit string must be <= 7!'); } var ret = []; for (var i = 1; i < value.length; i++) { var byte = value[i]; ret.push((byte & 128) ? 1 : 0, (byte & 64) ? 1 : 0, (byte & 32) ? 1 : 0, (byte & 16) ? 1 : 0, (byte & 8) ? 1 : 0, (byte & 4) ? 1 : 0, (byte & 2) ? 1 : 0, (byte & 1) ? 1 : 0); } var unusedBits = value[0]; var trailingBits = ret.slice(ret.length - unusedBits); for (var _i = 0, trailingBits_1 = trailingBits; _i < trailingBits_1.length; _i++) { var bit = trailingBits_1[_i]; if (bit !== 0) { throw new Error('bit string had a trailing set bit.'); } } ret.length -= unusedBits; return new Uint8ClampedArray(ret); }; /** * Decodes an ASN.1 BOOLEAN from bytes. * * @private * @param {Uint8Array} value The bytes to decode. * @returns {boolean} The decoded boolean. */ _PdfUniqueEncodingElement.prototype._decodeBoolean = function (value) { if (value.length !== 1) { throw new Error('Invalid Boolean format: Boolean values must be exactly one byte.'); } if (value[0] !== 0x00 && value[0] !== 0xff) { throw new Error('Boolean must be encoded as 0xFF or 0x00.'); } return value[0] !== 0x00; }; /** * Encodes a `_PdfCharacterString` structure into bytes suitable for this element. * * @private * @param {_PdfCharacterString} value The character-string structure to encode. * @returns {Uint8Array} The encoded bytes. */ _PdfUniqueEncodingElement.prototype._encodeCharacterString = function (value) { return this._encodeSequence([ value._identification, new _PdfUniqueEncodingElement(_TagClassType.universal, _ConstructionType.primitive, _UniversalType.octetString, value._stringValue) ]); }; /** * Decodes a sequence of unique encoding elements from bytes. * * @private * @param {Uint8Array} value The bytes to decode. * @returns {_PdfUniqueEncodingElement[]} Decoded unique elements. */ _PdfUniqueEncodingElement.prototype._decodeSequence = function (value) { if (value.length === 0) { return []; } var encodedElements = []; var i = 0; while (i < value.length) { var next = new _PdfUniqueEncodingElement(); var consumed = next._fromBytes(value.subarray(i)); i += consumed; encodedElements.push(next); } return encodedElements; }; /** * Wraps a sequence of abstract syntax elements into a unique encoding element. * * @private * @param {_PdfAbstractSyntaxElement[]} sequence The sequence elements. * @returns {_PdfUniqueEncodingElement} The wrapped unique element. */ _PdfUniqueEncodingElement.prototype._fromSequence = function (sequence) { var ret = new _PdfUniqueEncodingElement(_TagClassType.universal, _ConstructionType.constructed, _UniversalType.sequence); ret._setSequence(sequence.filter(function (element) { return Boolean(element); })); return ret; }; /** * Returns the external encoding represented by an encoding element, mapping tag options to values. * * @private * @param {_PdfAbstractSyntaxElement} encodingElement The encoding element describing the external. * @returns {_PdfAbstractSyntaxElement|Uint8Array|Uint8ClampedArray} The decoded external payload. */ _PdfUniqueEncodingElement.prototype._getExternalEncoding = function (encodingElement) { switch (encodingElement._getTagNumber()) { case 0: return encodingElement._getInner(); case 1: return encodingElement._getOctetString(); case 2: return encodingElement._getBitString(); default: throw new Error('External does not know of an encoding option ' + ("having tag number " + encodingElement._getTagNumber() + ".")); } }; /** * Returns the length in bytes of this element's encoded value. * * @private * @returns {number} The value length. */ _PdfUniqueEncodingElement.prototype._valueLength = function () { if (typeof this._currentValueLength !== 'undefined' && this._currentValueLength !== null && !Array.isArray(this._value)) { return this._currentValueLength; } if (!Array.isArray(this._value)) { var v = this._getValue(); this._currentValueLength = v.length; return v.length; } var len = 0; for (var _i = 0, _a = this._value; _i < _a.length; _i++) { var el = _a[_i]; len += el._tagValueLength(); //eslint-disable-line } this._currentValueLength = len; return len; }; /** * Computes the number of bytes required to encode the length field for a value length. * * @private * @param {number} [valueLength] Optional explicit value length to evaluate. * @returns {number} The number of bytes used to encode the length. */ _PdfUniqueEncodingElement.prototype._lengthLength = function (valueLength) { var len = (valueLength !== null && valueLength !== undefined) ? valueLength : this._valueLength(); if (len < 128) { return 1; } var n = 0; var v = len; while (v > 0) { n++; v >>>= 8; } return 1 + n; }; /** * Returns the total encoded length of this element including tag and length fields. * * @private * @returns {number} The combined tag+length+value length in bytes. */ _PdfUniqueEncodingElement.prototype._tagValueLength = function () { var value = this._valueLength(); return this._tagLength() + this._lengthLength(value) + value; }; return _PdfUniqueEncodingElement; }(_PdfAbstractSyntaxElement)); export { _PdfUniqueEncodingElement };