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