summaryrefslogtreecommitdiffstats
path: root/comm/third_party/asn1js/src/BitString.ts
blob: 2c8ada83cc08ac95007ba15d43f79ee71a04e524 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import { BaseBlock, BaseBlockJson, BaseBlockParams } from "./BaseBlock";
import { Constructed } from "./Constructed";
import { BIT_STRING_NAME } from "./internals/constants";
import { LocalBitStringValueBlockParams, LocalBitStringValueBlock, LocalBitStringValueBlockJson } from "./internals/LocalBitStringValueBlock";
import { typeStore } from "./TypeStore";

export interface BitStringParams extends BaseBlockParams, LocalBitStringValueBlockParams { }
export type BitStringJson = BaseBlockJson<LocalBitStringValueBlockJson>;

export class BitString extends BaseBlock<LocalBitStringValueBlock, LocalBitStringValueBlockJson> {

  static {
    typeStore.BitString = this;
  }

  public static override NAME = BIT_STRING_NAME;

  constructor({
    idBlock = {},
    lenBlock = {},
    ...parameters
  }: BitStringParams = {}) {
    parameters.isConstructed ??= !!parameters.value?.length;
    super({
      idBlock: {
        isConstructed: parameters.isConstructed,
        ...idBlock,
      },
      lenBlock: {
        ...lenBlock,
        isIndefiniteForm: !!parameters.isIndefiniteForm,
      },
      ...parameters,
    }, LocalBitStringValueBlock);

    this.idBlock.tagClass = 1; // UNIVERSAL
    this.idBlock.tagNumber = 3; // BitString
  }

  public override fromBER(inputBuffer: ArrayBuffer | Uint8Array, inputOffset: number, inputLength: number): number {
    this.valueBlock.isConstructed = this.idBlock.isConstructed;
    this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm;

    return super.fromBER(inputBuffer, inputOffset, inputLength);
  }

  protected override onAsciiEncoding(): string {
    if (this.valueBlock.isConstructed || (this.valueBlock.value && this.valueBlock.value.length)) {
      return Constructed.prototype.onAsciiEncoding.call(this);
    } else {
      // convert bytes to bits
      const bits = [];
      const valueHex = this.valueBlock.valueHexView;
      for (const byte of valueHex) {
        bits.push(byte.toString(2).padStart(8, "0"));
      }

      const bitsStr = bits.join("");

      return `${(this.constructor as typeof BitString).NAME} : ${bitsStr.substring(0, bitsStr.length - this.valueBlock.unusedBits)}`;
    }
  }

}