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