xref: /aosp_15_r20/external/flatbuffers/dart/lib/src/types.dart (revision 890232f25432b36107d06881e0a25aaa6b473652)
1import 'dart:typed_data';
2
3/// Represents the number of bits a value occupies.
4enum BitWidth { width8, width16, width32, width64 }
5
6class BitWidthUtil {
7  static int toByteWidth(BitWidth self) {
8    return 1 << self.index;
9  }
10
11  static BitWidth width(num value) {
12    if (value.toInt() == value) {
13      var v = value.toInt().abs();
14      if (v >> 7 == 0) return BitWidth.width8;
15      if (v >> 15 == 0) return BitWidth.width16;
16      if (v >> 31 == 0) return BitWidth.width32;
17      return BitWidth.width64;
18    }
19    return value == _toF32(value as double)
20        ? BitWidth.width32
21        : BitWidth.width64;
22  }
23
24  static BitWidth uwidth(num value) {
25    if (value.toInt() == value) {
26      var v = value.toInt().abs();
27      if (v >> 8 == 0) return BitWidth.width8;
28      if (v >> 16 == 0) return BitWidth.width16;
29      if (v >> 32 == 0) return BitWidth.width32;
30      return BitWidth.width64;
31    }
32    return value == _toF32(value as double)
33        ? BitWidth.width32
34        : BitWidth.width64;
35  }
36
37  static BitWidth fromByteWidth(int value) {
38    if (value == 1) {
39      return BitWidth.width8;
40    }
41    if (value == 2) {
42      return BitWidth.width16;
43    }
44    if (value == 4) {
45      return BitWidth.width32;
46    }
47    if (value == 8) {
48      return BitWidth.width64;
49    }
50    throw Exception('Unexpected value $value');
51  }
52
53  static int paddingSize(int bufSize, int scalarSize) {
54    return (~bufSize + 1) & (scalarSize - 1);
55  }
56
57  static double _toF32(double value) {
58    var bdata = ByteData(4);
59    bdata.setFloat32(0, value);
60    return bdata.getFloat32(0);
61  }
62
63  static BitWidth max(BitWidth self, BitWidth other) {
64    if (self.index < other.index) {
65      return other;
66    }
67    return self;
68  }
69}
70
71/// Represents all internal FlexBuffer types.
72enum ValueType {
73  Null,
74  Int,
75  UInt,
76  Float,
77  Key,
78  String,
79  IndirectInt,
80  IndirectUInt,
81  IndirectFloat,
82  Map,
83  Vector,
84  VectorInt,
85  VectorUInt,
86  VectorFloat,
87  VectorKey,
88  @Deprecated(
89      'VectorString is deprecated due to a flaw in the binary format (https://github.com/google/flatbuffers/issues/5627)')
90  VectorString,
91  VectorInt2,
92  VectorUInt2,
93  VectorFloat2,
94  VectorInt3,
95  VectorUInt3,
96  VectorFloat3,
97  VectorInt4,
98  VectorUInt4,
99  VectorFloat4,
100  Blob,
101  Bool,
102  VectorBool
103}
104
105class ValueTypeUtils {
106  static int toInt(ValueType self) {
107    if (self == ValueType.VectorBool) return 36;
108    return self.index;
109  }
110
111  static ValueType fromInt(int value) {
112    if (value == 36) return ValueType.VectorBool;
113    return ValueType.values[value];
114  }
115
116  static bool isInline(ValueType self) {
117    return self == ValueType.Bool || toInt(self) <= toInt(ValueType.Float);
118  }
119
120  static bool isNumber(ValueType self) {
121    return toInt(self) >= toInt(ValueType.Int) &&
122        toInt(self) <= toInt(ValueType.Float);
123  }
124
125  static bool isIndirectNumber(ValueType self) {
126    return toInt(self) >= toInt(ValueType.IndirectInt) &&
127        toInt(self) <= toInt(ValueType.IndirectFloat);
128  }
129
130  static bool isTypedVectorElement(ValueType self) {
131    return self == ValueType.Bool ||
132        (toInt(self) >= toInt(ValueType.Int) &&
133            toInt(self) <= toInt(ValueType.String));
134  }
135
136  static bool isTypedVector(ValueType self) {
137    return self == ValueType.VectorBool ||
138        (toInt(self) >= toInt(ValueType.VectorInt) &&
139            toInt(self) <= toInt(ValueType.VectorString));
140  }
141
142  static bool isFixedTypedVector(ValueType self) {
143    return (toInt(self) >= toInt(ValueType.VectorInt2) &&
144        toInt(self) <= toInt(ValueType.VectorFloat4));
145  }
146
147  static bool isAVector(ValueType self) {
148    return (isTypedVector(self) ||
149        isFixedTypedVector(self) ||
150        self == ValueType.Vector);
151  }
152
153  static ValueType toTypedVector(ValueType self, int length) {
154    if (length == 0) {
155      return ValueTypeUtils.fromInt(
156          toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt));
157    }
158    if (length == 2) {
159      return ValueTypeUtils.fromInt(
160          toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt2));
161    }
162    if (length == 3) {
163      return ValueTypeUtils.fromInt(
164          toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt3));
165    }
166    if (length == 4) {
167      return ValueTypeUtils.fromInt(
168          toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt4));
169    }
170    throw Exception('unexpected length ' + length.toString());
171  }
172
173  static ValueType typedVectorElementType(ValueType self) {
174    return ValueTypeUtils.fromInt(
175        toInt(self) - toInt(ValueType.VectorInt) + toInt(ValueType.Int));
176  }
177
178  static ValueType fixedTypedVectorElementType(ValueType self) {
179    return ValueTypeUtils.fromInt(
180        (toInt(self) - toInt(ValueType.VectorInt2)) % 3 + toInt(ValueType.Int));
181  }
182
183  static int fixedTypedVectorElementSize(ValueType self) {
184    return (toInt(self) - toInt(ValueType.VectorInt2)) ~/ 3 + 2;
185  }
186
187  static int packedType(ValueType self, BitWidth bitWidth) {
188    return bitWidth.index | (toInt(self) << 2);
189  }
190}
191