summaryrefslogtreecommitdiffstats
path: root/comm/third_party/asn1js/src/internals/LocalIntegerValueBlock.ts
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/asn1js/src/internals/LocalIntegerValueBlock.ts')
-rw-r--r--comm/third_party/asn1js/src/internals/LocalIntegerValueBlock.ts330
1 files changed, 330 insertions, 0 deletions
diff --git a/comm/third_party/asn1js/src/internals/LocalIntegerValueBlock.ts b/comm/third_party/asn1js/src/internals/LocalIntegerValueBlock.ts
new file mode 100644
index 0000000000..3a7b299caf
--- /dev/null
+++ b/comm/third_party/asn1js/src/internals/LocalIntegerValueBlock.ts
@@ -0,0 +1,330 @@
+/* eslint-disable @typescript-eslint/ban-ts-comment */
+import * as pvutils from "pvutils";
+import { HexBlockJson, HexBlockParams, HexBlock } from "../HexBlock";
+import { IDerConvertible } from "../types";
+import { ValueBlock, ValueBlockJson, ValueBlockParams } from "../ValueBlock";
+import { powers2, digitsString } from "./constants";
+
+function viewAdd(first: Uint8Array, second: Uint8Array): Uint8Array {
+ //#region Initial variables
+ const c = new Uint8Array([0]);
+
+ const firstView = new Uint8Array(first);
+ const secondView = new Uint8Array(second);
+
+ let firstViewCopy = firstView.slice(0);
+ const firstViewCopyLength = firstViewCopy.length - 1;
+ const secondViewCopy = secondView.slice(0);
+ const secondViewCopyLength = secondViewCopy.length - 1;
+
+ let value = 0;
+
+ const max = (secondViewCopyLength < firstViewCopyLength) ? firstViewCopyLength : secondViewCopyLength;
+
+ let counter = 0;
+ //#endregion
+ for (let i = max; i >= 0; i--, counter++) {
+ switch (true) {
+ case (counter < secondViewCopy.length):
+ value = firstViewCopy[firstViewCopyLength - counter] + secondViewCopy[secondViewCopyLength - counter] + c[0];
+ break;
+ default:
+ value = firstViewCopy[firstViewCopyLength - counter] + c[0];
+ }
+
+ c[0] = value / 10;
+
+ switch (true) {
+ case (counter >= firstViewCopy.length):
+ firstViewCopy = pvutils.utilConcatView(new Uint8Array([value % 10]), firstViewCopy);
+ break;
+ default:
+ firstViewCopy[firstViewCopyLength - counter] = value % 10;
+ }
+ }
+
+ if (c[0] > 0)
+ firstViewCopy = pvutils.utilConcatView(c, firstViewCopy);
+
+ return firstViewCopy;
+}
+
+function power2(n: number): Uint8Array {
+ if (n >= powers2.length) {
+ for (let p = powers2.length; p <= n; p++) {
+ const c = new Uint8Array([0]);
+ let digits = (powers2[p - 1]).slice(0);
+
+ for (let i = (digits.length - 1); i >= 0; i--) {
+ const newValue = new Uint8Array([(digits[i] << 1) + c[0]]);
+ c[0] = newValue[0] / 10;
+ digits[i] = newValue[0] % 10;
+ }
+
+ if (c[0] > 0)
+ digits = pvutils.utilConcatView(c, digits);
+
+ powers2.push(digits);
+ }
+ }
+
+ return powers2[n];
+}
+
+function viewSub(first: Uint8Array, second: Uint8Array): Uint8Array {
+ //#region Initial variables
+ let b = 0;
+
+ const firstView = new Uint8Array(first);
+ const secondView = new Uint8Array(second);
+
+ const firstViewCopy = firstView.slice(0);
+ const firstViewCopyLength = firstViewCopy.length - 1;
+ const secondViewCopy = secondView.slice(0);
+ const secondViewCopyLength = secondViewCopy.length - 1;
+
+ let value;
+
+ let counter = 0;
+ //#endregion
+ for (let i = secondViewCopyLength; i >= 0; i--, counter++) {
+ value = firstViewCopy[firstViewCopyLength - counter] - secondViewCopy[secondViewCopyLength - counter] - b;
+
+ switch (true) {
+ case (value < 0):
+ b = 1;
+ firstViewCopy[firstViewCopyLength - counter] = value + 10;
+ break;
+ default:
+ b = 0;
+ firstViewCopy[firstViewCopyLength - counter] = value;
+ }
+ }
+
+ if (b > 0) {
+ for (let i = (firstViewCopyLength - secondViewCopyLength + 1); i >= 0; i--, counter++) {
+ value = firstViewCopy[firstViewCopyLength - counter] - b;
+
+ if (value < 0) {
+ b = 1;
+ firstViewCopy[firstViewCopyLength - counter] = value + 10;
+ }
+ else {
+ b = 0;
+ firstViewCopy[firstViewCopyLength - counter] = value;
+ break;
+ }
+ }
+ }
+
+ return firstViewCopy.slice();
+}
+
+export interface ILocalIntegerValueBlock {
+ value: number;
+}
+
+export interface LocalIntegerValueBlockParams extends HexBlockParams, ValueBlockParams, Partial<ILocalIntegerValueBlock> { }
+
+export interface LocalIntegerValueBlockJson extends HexBlockJson, ValueBlockJson {
+ valueDec: number;
+}
+
+export class LocalIntegerValueBlock extends HexBlock(ValueBlock) implements IDerConvertible {
+ protected setValueHex(): void {
+ if (this.valueHexView.length >= 4) {
+ this.warnings.push("Too big Integer for decoding, hex only");
+ this.isHexOnly = true;
+ this._valueDec = 0;
+ } else {
+ this.isHexOnly = false;
+
+ if (this.valueHexView.length > 0) {
+ this._valueDec = pvutils.utilDecodeTC.call(this);
+ }
+ }
+ }
+
+ public static override NAME = "IntegerValueBlock";
+
+ static {
+ Object.defineProperty(this.prototype, "valueHex", {
+ set: function (this: LocalIntegerValueBlock, v: ArrayBuffer) {
+ this.valueHexView = new Uint8Array(v);
+
+ this.setValueHex();
+ },
+ get: function (this: LocalIntegerValueBlock) {
+ return this.valueHexView.slice().buffer;
+ },
+ });
+ }
+
+ private _valueDec = 0;
+
+ constructor({
+ value,
+ ...parameters
+ }: LocalIntegerValueBlockParams = {}) {
+ super(parameters);
+
+ if (parameters.valueHex) {
+ this.setValueHex();
+ }
+
+ if (value !== undefined) {
+ this.valueDec = value;
+ }
+ }
+
+ public set valueDec(v: number) {
+ this._valueDec = v;
+
+ this.isHexOnly = false;
+ this.valueHexView = new Uint8Array(pvutils.utilEncodeTC(v));
+ }
+
+ public get valueDec(): number {
+ return this._valueDec;
+ }
+
+ public fromDER(inputBuffer: ArrayBuffer, inputOffset: number, inputLength: number, expectedLength = 0): number {
+ const offset = this.fromBER(inputBuffer, inputOffset, inputLength);
+ if (offset === -1)
+ return offset;
+
+ const view = this.valueHexView;
+
+ if ((view[0] === 0x00) && ((view[1] & 0x80) !== 0)) {
+ this.valueHexView = view.subarray(1);
+ }
+ else {
+ if (expectedLength !== 0) {
+ if (view.length < expectedLength) {
+ if ((expectedLength - view.length) > 1)
+ expectedLength = view.length + 1;
+
+ this.valueHexView = view.subarray(expectedLength - view.length);
+ }
+ }
+ }
+
+ return offset;
+ }
+
+ public toDER(sizeOnly = false): ArrayBuffer {
+ const view = this.valueHexView;
+
+ switch (true) {
+ case ((view[0] & 0x80) !== 0):
+ {
+ const updatedView = new Uint8Array(this.valueHexView.length + 1);
+
+ updatedView[0] = 0x00;
+ updatedView.set(view, 1);
+
+ this.valueHexView = updatedView;
+ }
+ break;
+ case ((view[0] === 0x00) && ((view[1] & 0x80) === 0)):
+ {
+ this.valueHexView = this.valueHexView.subarray(1);
+ }
+ break;
+ default:
+ }
+
+ return this.toBER(sizeOnly);
+ }
+
+ public override fromBER(inputBuffer: ArrayBuffer, inputOffset: number, inputLength: number): number {
+ const resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength);
+ if (resultOffset === -1) {
+ return resultOffset;
+ }
+
+ this.setValueHex();
+
+ return resultOffset;
+ }
+
+ public override toBER(sizeOnly?: boolean): ArrayBuffer {
+ return sizeOnly
+ ? new ArrayBuffer(this.valueHexView.length)
+ : this.valueHexView.slice().buffer;
+ }
+
+ public override toJSON(): LocalIntegerValueBlockJson {
+ return {
+ ...super.toJSON(),
+ valueDec: this.valueDec,
+ };
+ }
+
+ public override toString(): string {
+ //#region Initial variables
+ const firstBit = (this.valueHexView.length * 8) - 1;
+
+ let digits = new Uint8Array((this.valueHexView.length * 8) / 3);
+ let bitNumber = 0;
+ let currentByte;
+
+ const asn1View = this.valueHexView;
+
+ let result = "";
+
+ let flag = false;
+ //#endregion
+ //#region Calculate number
+ for (let byteNumber = (asn1View.byteLength - 1); byteNumber >= 0; byteNumber--) {
+ currentByte = asn1View[byteNumber];
+
+ for (let i = 0; i < 8; i++) {
+ if ((currentByte & 1) === 1) {
+ switch (bitNumber) {
+ case firstBit:
+ digits = viewSub(power2(bitNumber), digits);
+ result = "-";
+ break;
+ default:
+ digits = viewAdd(digits, power2(bitNumber));
+ }
+ }
+
+ bitNumber++;
+ currentByte >>= 1;
+ }
+ }
+ //#endregion
+ //#region Print number
+ for (let i = 0; i < digits.length; i++) {
+ if (digits[i])
+ flag = true;
+
+ if (flag)
+ result += digitsString.charAt(digits[i]);
+ }
+
+ if (flag === false)
+ result += digitsString.charAt(0);
+ //#endregion
+
+ return result;
+ }
+
+}
+
+export interface LocalIntegerValueBlock {
+ /**
+ * @deprecated since version 3.0.0
+ */
+ // @ts-ignore
+ valueBeforeDecode: ArrayBuffer;
+ /**
+ * Binary data in ArrayBuffer representation
+ *
+ * @deprecated since version 3.0.0
+ */
+ // @ts-ignore
+ valueHex: ArrayBuffer;
+}