xref: /aosp_15_r20/external/flatbuffers/ts/flexbuffers/stack-value.ts (revision 890232f25432b36107d06881e0a25aaa6b473652)
1*890232f2SAndroid Build Coastguard Workerimport { Builder } from './builder.js'
2*890232f2SAndroid Build Coastguard Workerimport { BitWidth } from './bit-width.js'
3*890232f2SAndroid Build Coastguard Workerimport { paddingSize, uwidth, fromByteWidth } from './bit-width-util.js'
4*890232f2SAndroid Build Coastguard Workerimport { ValueType } from './value-type.js'
5*890232f2SAndroid Build Coastguard Workerimport { isInline, packedType } from './value-type-util.js'
6*890232f2SAndroid Build Coastguard Worker
7*890232f2SAndroid Build Coastguard Workerexport class StackValue {
8*890232f2SAndroid Build Coastguard Worker  constructor(private builder: Builder, public type: ValueType, public width: number, public value: number | boolean | null = null, public offset: number = 0) {
9*890232f2SAndroid Build Coastguard Worker
10*890232f2SAndroid Build Coastguard Worker  }
11*890232f2SAndroid Build Coastguard Worker
12*890232f2SAndroid Build Coastguard Worker  elementWidth(size: number, index: number): BitWidth {
13*890232f2SAndroid Build Coastguard Worker    if (isInline(this.type)) return this.width;
14*890232f2SAndroid Build Coastguard Worker    for (let i = 0; i < 4; i++) {
15*890232f2SAndroid Build Coastguard Worker      const width = 1 << i;
16*890232f2SAndroid Build Coastguard Worker      const offsetLoc = size + paddingSize(size, width) + index * width;
17*890232f2SAndroid Build Coastguard Worker      const offset = offsetLoc - this.offset;
18*890232f2SAndroid Build Coastguard Worker      const bitWidth = uwidth(offset);
19*890232f2SAndroid Build Coastguard Worker      if (1 << bitWidth === width) {
20*890232f2SAndroid Build Coastguard Worker        return bitWidth;
21*890232f2SAndroid Build Coastguard Worker      }
22*890232f2SAndroid Build Coastguard Worker    }
23*890232f2SAndroid Build Coastguard Worker    throw `Element is unknown. Size: ${size} at index: ${index}. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new`;
24*890232f2SAndroid Build Coastguard Worker  }
25*890232f2SAndroid Build Coastguard Worker
26*890232f2SAndroid Build Coastguard Worker  writeToBuffer(byteWidth: number): void {
27*890232f2SAndroid Build Coastguard Worker    const newOffset = this.builder.computeOffset(byteWidth);
28*890232f2SAndroid Build Coastguard Worker    if (this.type === ValueType.FLOAT) {
29*890232f2SAndroid Build Coastguard Worker      if (this.width === BitWidth.WIDTH32) {
30*890232f2SAndroid Build Coastguard Worker        this.builder.view.setFloat32(this.builder.offset, this.value as number, true);
31*890232f2SAndroid Build Coastguard Worker      } else {
32*890232f2SAndroid Build Coastguard Worker        this.builder.view.setFloat64(this.builder.offset, this.value as number, true);
33*890232f2SAndroid Build Coastguard Worker      }
34*890232f2SAndroid Build Coastguard Worker    } else if (this.type === ValueType.INT) {
35*890232f2SAndroid Build Coastguard Worker      const bitWidth = fromByteWidth(byteWidth);
36*890232f2SAndroid Build Coastguard Worker      this.builder.pushInt(this.value as number, bitWidth);
37*890232f2SAndroid Build Coastguard Worker    } else if (this.type === ValueType.UINT) {
38*890232f2SAndroid Build Coastguard Worker      const bitWidth = fromByteWidth(byteWidth);
39*890232f2SAndroid Build Coastguard Worker      this.builder.pushUInt(this.value as number, bitWidth);
40*890232f2SAndroid Build Coastguard Worker    } else if (this.type === ValueType.NULL) {
41*890232f2SAndroid Build Coastguard Worker      this.builder.pushInt(0, this.width);
42*890232f2SAndroid Build Coastguard Worker    } else if (this.type === ValueType.BOOL) {
43*890232f2SAndroid Build Coastguard Worker      this.builder.pushInt(this.value ? 1 : 0, this.width);
44*890232f2SAndroid Build Coastguard Worker    } else {
45*890232f2SAndroid Build Coastguard Worker      throw `Unexpected type: ${this.type}. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new`
46*890232f2SAndroid Build Coastguard Worker    }
47*890232f2SAndroid Build Coastguard Worker    this.offset = newOffset;
48*890232f2SAndroid Build Coastguard Worker  }
49*890232f2SAndroid Build Coastguard Worker
50*890232f2SAndroid Build Coastguard Worker  storedWidth(width = BitWidth.WIDTH8): BitWidth {
51*890232f2SAndroid Build Coastguard Worker    return isInline(this.type) ? Math.max(width, this.width) : this.width;
52*890232f2SAndroid Build Coastguard Worker  }
53*890232f2SAndroid Build Coastguard Worker
54*890232f2SAndroid Build Coastguard Worker  storedPackedType(width = BitWidth.WIDTH8): ValueType {
55*890232f2SAndroid Build Coastguard Worker    return packedType(this.type, this.storedWidth(width));
56*890232f2SAndroid Build Coastguard Worker  }
57*890232f2SAndroid Build Coastguard Worker
58*890232f2SAndroid Build Coastguard Worker  isOffset(): boolean {
59*890232f2SAndroid Build Coastguard Worker    return !isInline(this.type)
60*890232f2SAndroid Build Coastguard Worker  }
61*890232f2SAndroid Build Coastguard Worker}