Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame^] | 1 | import { Builder } from './builder' |
| 2 | import { BitWidth } from './bit-width' |
| 3 | import { paddingSize, uwidth, fromByteWidth } from './bit-width-util' |
| 4 | import { ValueType } from './value-type' |
| 5 | import { isInline, packedType } from './value-type-util' |
| 6 | |
| 7 | export 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 | } |