@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
JavaScript
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 };