m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1536 lines
43 KiB

6 months ago
  1. # Lint as: python3
  2. # Copyright 2020 Google Inc. All rights reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. """Implementation of FlexBuffers binary format.
  16. For more info check https://google.github.io/flatbuffers/flexbuffers.html and
  17. corresponding C++ implementation at
  18. https://github.com/google/flatbuffers/blob/master/include/flatbuffers/flexbuffers.h
  19. """
  20. # pylint: disable=invalid-name
  21. # TODO(dkovalev): Add type hints everywhere, so tools like pytypes could work.
  22. import array
  23. import contextlib
  24. import enum
  25. import struct
  26. __all__ = ('Type', 'Builder', 'GetRoot', 'Dumps', 'Loads')
  27. class BitWidth(enum.IntEnum):
  28. """Supported bit widths of value types.
  29. These are used in the lower 2 bits of a type field to determine the size of
  30. the elements (and or size field) of the item pointed to (e.g. vector).
  31. """
  32. W8 = 0 # 2^0 = 1 byte
  33. W16 = 1 # 2^1 = 2 bytes
  34. W32 = 2 # 2^2 = 4 bytes
  35. W64 = 3 # 2^3 = 8 bytes
  36. @staticmethod
  37. def U(value):
  38. """Returns the minimum `BitWidth` to encode unsigned integer value."""
  39. assert value >= 0
  40. if value < (1 << 8):
  41. return BitWidth.W8
  42. elif value < (1 << 16):
  43. return BitWidth.W16
  44. elif value < (1 << 32):
  45. return BitWidth.W32
  46. elif value < (1 << 64):
  47. return BitWidth.W64
  48. else:
  49. raise ValueError('value is too big to encode: %s' % value)
  50. @staticmethod
  51. def I(value):
  52. """Returns the minimum `BitWidth` to encode signed integer value."""
  53. # -2^(n-1) <= value < 2^(n-1)
  54. # -2^n <= 2 * value < 2^n
  55. # 2 * value < 2^n, when value >= 0 or 2 * (-value) <= 2^n, when value < 0
  56. # 2 * value < 2^n, when value >= 0 or 2 * (-value) - 1 < 2^n, when value < 0
  57. #
  58. # if value >= 0:
  59. # return BitWidth.U(2 * value)
  60. # else:
  61. # return BitWidth.U(2 * (-value) - 1) # ~x = -x - 1
  62. value *= 2
  63. return BitWidth.U(value if value >= 0 else ~value)
  64. @staticmethod
  65. def F(value):
  66. """Returns the `BitWidth` to encode floating point value."""
  67. if struct.unpack('<f', struct.pack('<f', value))[0] == value:
  68. return BitWidth.W32
  69. return BitWidth.W64
  70. @staticmethod
  71. def B(byte_width):
  72. return {
  73. 1: BitWidth.W8,
  74. 2: BitWidth.W16,
  75. 4: BitWidth.W32,
  76. 8: BitWidth.W64
  77. }[byte_width]
  78. I = {1: 'b', 2: 'h', 4: 'i', 8: 'q'} # Integer formats
  79. U = {1: 'B', 2: 'H', 4: 'I', 8: 'Q'} # Unsigned integer formats
  80. F = {4: 'f', 8: 'd'} # Floating point formats
  81. def _Unpack(fmt, buf):
  82. return struct.unpack('<%s' % fmt[len(buf)], buf)[0]
  83. def _UnpackVector(fmt, buf, length):
  84. byte_width = len(buf) // length
  85. return struct.unpack('<%d%s' % (length, fmt[byte_width]), buf)
  86. def _Pack(fmt, value, byte_width):
  87. return struct.pack('<%s' % fmt[byte_width], value)
  88. def _PackVector(fmt, values, byte_width):
  89. return struct.pack('<%d%s' % (len(values), fmt[byte_width]), *values)
  90. def _Mutate(fmt, buf, value, byte_width, value_bit_width):
  91. if (1 << value_bit_width) <= byte_width:
  92. buf[:byte_width] = _Pack(fmt, value, byte_width)
  93. return True
  94. return False
  95. # Computes how many bytes you'd have to pad to be able to write an
  96. # "scalar_size" scalar if the buffer had grown to "buf_size",
  97. # "scalar_size" is a power of two.
  98. def _PaddingBytes(buf_size, scalar_size):
  99. # ((buf_size + (scalar_size - 1)) // scalar_size) * scalar_size - buf_size
  100. return -buf_size & (scalar_size - 1)
  101. def _ShiftSlice(s, offset, length):
  102. start = offset + (0 if s.start is None else s.start)
  103. stop = offset + (length if s.stop is None else s.stop)
  104. return slice(start, stop, s.step)
  105. # https://en.cppreference.com/w/cpp/algorithm/lower_bound
  106. def _LowerBound(values, value, pred):
  107. """Implementation of C++ std::lower_bound() algorithm."""
  108. first, last = 0, len(values)
  109. count = last - first
  110. while count > 0:
  111. i = first
  112. step = count // 2
  113. i += step
  114. if pred(values[i], value):
  115. i += 1
  116. first = i
  117. count -= step + 1
  118. else:
  119. count = step
  120. return first
  121. # https://en.cppreference.com/w/cpp/algorithm/binary_search
  122. def _BinarySearch(values, value, pred=lambda x, y: x < y):
  123. """Implementation of C++ std::binary_search() algorithm."""
  124. index = _LowerBound(values, value, pred)
  125. if index != len(values) and not pred(value, values[index]):
  126. return index
  127. return -1
  128. class Type(enum.IntEnum):
  129. """Supported types of encoded data.
  130. These are used as the upper 6 bits of a type field to indicate the actual
  131. type.
  132. """
  133. NULL = 0
  134. INT = 1
  135. UINT = 2
  136. FLOAT = 3
  137. # Types above stored inline, types below store an offset.
  138. KEY = 4
  139. STRING = 5
  140. INDIRECT_INT = 6
  141. INDIRECT_UINT = 7
  142. INDIRECT_FLOAT = 8
  143. MAP = 9
  144. VECTOR = 10 # Untyped.
  145. VECTOR_INT = 11 # Typed any size (stores no type table).
  146. VECTOR_UINT = 12
  147. VECTOR_FLOAT = 13
  148. VECTOR_KEY = 14
  149. # DEPRECATED, use VECTOR or VECTOR_KEY instead.
  150. # Read test.cpp/FlexBuffersDeprecatedTest() for details on why.
  151. VECTOR_STRING_DEPRECATED = 15
  152. VECTOR_INT2 = 16 # Typed tuple (no type table, no size field).
  153. VECTOR_UINT2 = 17
  154. VECTOR_FLOAT2 = 18
  155. VECTOR_INT3 = 19 # Typed triple (no type table, no size field).
  156. VECTOR_UINT3 = 20
  157. VECTOR_FLOAT3 = 21
  158. VECTOR_INT4 = 22 # Typed quad (no type table, no size field).
  159. VECTOR_UINT4 = 23
  160. VECTOR_FLOAT4 = 24
  161. BLOB = 25
  162. BOOL = 26
  163. VECTOR_BOOL = 36 # To do the same type of conversion of type to vector type
  164. @staticmethod
  165. def Pack(type_, bit_width):
  166. return (int(type_) << 2) | bit_width
  167. @staticmethod
  168. def Unpack(packed_type):
  169. return 1 << (packed_type & 0b11), Type(packed_type >> 2)
  170. @staticmethod
  171. def IsInline(type_):
  172. return type_ <= Type.FLOAT or type_ == Type.BOOL
  173. @staticmethod
  174. def IsTypedVector(type_):
  175. return Type.VECTOR_INT <= type_ <= Type.VECTOR_STRING_DEPRECATED or \
  176. type_ == Type.VECTOR_BOOL
  177. @staticmethod
  178. def IsTypedVectorElementType(type_):
  179. return Type.INT <= type_ <= Type.STRING or type_ == Type.BOOL
  180. @staticmethod
  181. def ToTypedVectorElementType(type_):
  182. if not Type.IsTypedVector(type_):
  183. raise ValueError('must be typed vector type')
  184. return Type(type_ - Type.VECTOR_INT + Type.INT)
  185. @staticmethod
  186. def IsFixedTypedVector(type_):
  187. return Type.VECTOR_INT2 <= type_ <= Type.VECTOR_FLOAT4
  188. @staticmethod
  189. def IsFixedTypedVectorElementType(type_):
  190. return Type.INT <= type_ <= Type.FLOAT
  191. @staticmethod
  192. def ToFixedTypedVectorElementType(type_):
  193. if not Type.IsFixedTypedVector(type_):
  194. raise ValueError('must be fixed typed vector type')
  195. # 3 types each, starting from length 2.
  196. fixed_type = type_ - Type.VECTOR_INT2
  197. return Type(fixed_type % 3 + Type.INT), fixed_type // 3 + 2
  198. @staticmethod
  199. def ToTypedVector(element_type, fixed_len=0):
  200. """Converts element type to corresponding vector type.
  201. Args:
  202. element_type: vector element type
  203. fixed_len: number of elements: 0 for typed vector; 2, 3, or 4 for fixed
  204. typed vector.
  205. Returns:
  206. Typed vector type or fixed typed vector type.
  207. """
  208. if fixed_len == 0:
  209. if not Type.IsTypedVectorElementType(element_type):
  210. raise ValueError('must be typed vector element type')
  211. else:
  212. if not Type.IsFixedTypedVectorElementType(element_type):
  213. raise ValueError('must be fixed typed vector element type')
  214. offset = element_type - Type.INT
  215. if fixed_len == 0:
  216. return Type(offset + Type.VECTOR_INT) # TypedVector
  217. elif fixed_len == 2:
  218. return Type(offset + Type.VECTOR_INT2) # FixedTypedVector
  219. elif fixed_len == 3:
  220. return Type(offset + Type.VECTOR_INT3) # FixedTypedVector
  221. elif fixed_len == 4:
  222. return Type(offset + Type.VECTOR_INT4) # FixedTypedVector
  223. else:
  224. raise ValueError('unsupported fixed_len: %s' % fixed_len)
  225. class Buf:
  226. """Class to access underlying buffer object starting from the given offset."""
  227. def __init__(self, buf, offset):
  228. self._buf = buf
  229. self._offset = offset if offset >= 0 else len(buf) + offset
  230. self._length = len(buf) - self._offset
  231. def __getitem__(self, key):
  232. if isinstance(key, slice):
  233. return self._buf[_ShiftSlice(key, self._offset, self._length)]
  234. elif isinstance(key, int):
  235. return self._buf[self._offset + key]
  236. else:
  237. raise TypeError('invalid key type')
  238. def __setitem__(self, key, value):
  239. if isinstance(key, slice):
  240. self._buf[_ShiftSlice(key, self._offset, self._length)] = value
  241. elif isinstance(key, int):
  242. self._buf[self._offset + key] = key
  243. else:
  244. raise TypeError('invalid key type')
  245. def __repr__(self):
  246. return 'buf[%d:]' % self._offset
  247. def Find(self, sub):
  248. """Returns the lowest index where the sub subsequence is found."""
  249. return self._buf[self._offset:].find(sub)
  250. def Slice(self, offset):
  251. """Returns new `Buf` which starts from the given offset."""
  252. return Buf(self._buf, self._offset + offset)
  253. def Indirect(self, offset, byte_width):
  254. """Return new `Buf` based on the encoded offset (indirect encoding)."""
  255. return self.Slice(offset - _Unpack(U, self[offset:offset + byte_width]))
  256. class Object:
  257. """Base class for all non-trivial data accessors."""
  258. __slots__ = '_buf', '_byte_width'
  259. def __init__(self, buf, byte_width):
  260. self._buf = buf
  261. self._byte_width = byte_width
  262. @property
  263. def ByteWidth(self):
  264. return self._byte_width
  265. class Sized(Object):
  266. """Base class for all data accessors which need to read encoded size."""
  267. __slots__ = '_size',
  268. def __init__(self, buf, byte_width, size=0):
  269. super().__init__(buf, byte_width)
  270. if size == 0:
  271. self._size = _Unpack(U, self.SizeBytes)
  272. else:
  273. self._size = size
  274. @property
  275. def SizeBytes(self):
  276. return self._buf[-self._byte_width:0]
  277. def __len__(self):
  278. return self._size
  279. class Blob(Sized):
  280. """Data accessor for the encoded blob bytes."""
  281. __slots__ = ()
  282. @property
  283. def Bytes(self):
  284. return self._buf[0:len(self)]
  285. def __repr__(self):
  286. return 'Blob(%s, size=%d)' % (self._buf, len(self))
  287. class String(Sized):
  288. """Data accessor for the encoded string bytes."""
  289. __slots__ = ()
  290. @property
  291. def Bytes(self):
  292. return self._buf[0:len(self)]
  293. def Mutate(self, value):
  294. """Mutates underlying string bytes in place.
  295. Args:
  296. value: New string to replace the existing one. New string must have less
  297. or equal UTF-8-encoded bytes than the existing one to successfully
  298. mutate underlying byte buffer.
  299. Returns:
  300. Whether the value was mutated or not.
  301. """
  302. encoded = value.encode('utf-8')
  303. n = len(encoded)
  304. if n <= len(self):
  305. self._buf[-self._byte_width:0] = _Pack(U, n, self._byte_width)
  306. self._buf[0:n] = encoded
  307. self._buf[n:len(self)] = bytearray(len(self) - n)
  308. return True
  309. return False
  310. def __str__(self):
  311. return self.Bytes.decode('utf-8')
  312. def __repr__(self):
  313. return 'String(%s, size=%d)' % (self._buf, len(self))
  314. class Key(Object):
  315. """Data accessor for the encoded key bytes."""
  316. __slots__ = ()
  317. def __init__(self, buf, byte_width):
  318. assert byte_width == 1
  319. super().__init__(buf, byte_width)
  320. @property
  321. def Bytes(self):
  322. return self._buf[0:len(self)]
  323. def __len__(self):
  324. return self._buf.Find(0)
  325. def __str__(self):
  326. return self.Bytes.decode('ascii')
  327. def __repr__(self):
  328. return 'Key(%s, size=%d)' % (self._buf, len(self))
  329. class Vector(Sized):
  330. """Data accessor for the encoded vector bytes."""
  331. __slots__ = ()
  332. def __getitem__(self, index):
  333. if index < 0 or index >= len(self):
  334. raise IndexError('vector index %s is out of [0, %d) range' % \
  335. (index, len(self)))
  336. packed_type = self._buf[len(self) * self._byte_width + index]
  337. buf = self._buf.Slice(index * self._byte_width)
  338. return Ref.PackedType(buf, self._byte_width, packed_type)
  339. @property
  340. def Value(self):
  341. """Returns the underlying encoded data as a list object."""
  342. return [e.Value for e in self]
  343. def __repr__(self):
  344. return 'Vector(%s, byte_width=%d, size=%d)' % \
  345. (self._buf, self._byte_width, self._size)
  346. class TypedVector(Sized):
  347. """Data accessor for the encoded typed vector or fixed typed vector bytes."""
  348. __slots__ = '_element_type', '_size'
  349. def __init__(self, buf, byte_width, element_type, size=0):
  350. super().__init__(buf, byte_width, size)
  351. if element_type == Type.STRING:
  352. # These can't be accessed as strings, since we don't know the bit-width
  353. # of the size field, see the declaration of
  354. # FBT_VECTOR_STRING_DEPRECATED above for details.
  355. # We change the type here to be keys, which are a subtype of strings,
  356. # and will ignore the size field. This will truncate strings with
  357. # embedded nulls.
  358. element_type = Type.KEY
  359. self._element_type = element_type
  360. @property
  361. def Bytes(self):
  362. return self._buf[:self._byte_width * len(self)]
  363. @property
  364. def ElementType(self):
  365. return self._element_type
  366. def __getitem__(self, index):
  367. if index < 0 or index >= len(self):
  368. raise IndexError('vector index %s is out of [0, %d) range' % \
  369. (index, len(self)))
  370. buf = self._buf.Slice(index * self._byte_width)
  371. return Ref(buf, self._byte_width, 1, self._element_type)
  372. @property
  373. def Value(self):
  374. """Returns underlying data as list object."""
  375. if not self:
  376. return []
  377. if self._element_type is Type.BOOL:
  378. return [bool(e) for e in _UnpackVector(U, self.Bytes, len(self))]
  379. elif self._element_type is Type.INT:
  380. return list(_UnpackVector(I, self.Bytes, len(self)))
  381. elif self._element_type is Type.UINT:
  382. return list(_UnpackVector(U, self.Bytes, len(self)))
  383. elif self._element_type is Type.FLOAT:
  384. return list(_UnpackVector(F, self.Bytes, len(self)))
  385. elif self._element_type is Type.KEY:
  386. return [e.AsKey for e in self]
  387. elif self._element_type is Type.STRING:
  388. return [e.AsString for e in self]
  389. else:
  390. raise TypeError('unsupported element_type: %s' % self._element_type)
  391. def __repr__(self):
  392. return 'TypedVector(%s, byte_width=%d, element_type=%s, size=%d)' % \
  393. (self._buf, self._byte_width, self._element_type, self._size)
  394. class Map(Vector):
  395. """Data accessor for the encoded map bytes."""
  396. @staticmethod
  397. def CompareKeys(a, b):
  398. if isinstance(a, Ref):
  399. a = a.AsKeyBytes
  400. if isinstance(b, Ref):
  401. b = b.AsKeyBytes
  402. return a < b
  403. def __getitem__(self, key):
  404. if isinstance(key, int):
  405. return super().__getitem__(key)
  406. index = _BinarySearch(self.Keys, key.encode('ascii'), self.CompareKeys)
  407. if index != -1:
  408. return super().__getitem__(index)
  409. raise KeyError(key)
  410. @property
  411. def Keys(self):
  412. byte_width = _Unpack(U, self._buf[-2 * self._byte_width:-self._byte_width])
  413. buf = self._buf.Indirect(-3 * self._byte_width, self._byte_width)
  414. return TypedVector(buf, byte_width, Type.KEY)
  415. @property
  416. def Values(self):
  417. return Vector(self._buf, self._byte_width)
  418. @property
  419. def Value(self):
  420. return {k.Value: v.Value for k, v in zip(self.Keys, self.Values)}
  421. def __repr__(self):
  422. return 'Map(%s, size=%d)' % (self._buf, len(self))
  423. class Ref:
  424. """Data accessor for the encoded data bytes."""
  425. __slots__ = '_buf', '_parent_width', '_byte_width', '_type'
  426. @staticmethod
  427. def PackedType(buf, parent_width, packed_type):
  428. byte_width, type_ = Type.Unpack(packed_type)
  429. return Ref(buf, parent_width, byte_width, type_)
  430. def __init__(self, buf, parent_width, byte_width, type_):
  431. self._buf = buf
  432. self._parent_width = parent_width
  433. self._byte_width = byte_width
  434. self._type = type_
  435. def __repr__(self):
  436. return 'Ref(%s, parent_width=%d, byte_width=%d, type_=%s)' % \
  437. (self._buf, self._parent_width, self._byte_width, self._type)
  438. @property
  439. def _Bytes(self):
  440. return self._buf[:self._parent_width]
  441. def _ConvertError(self, target_type):
  442. raise TypeError('cannot convert %s to %s' % (self._type, target_type))
  443. def _Indirect(self):
  444. return self._buf.Indirect(0, self._parent_width)
  445. @property
  446. def IsNull(self):
  447. return self._type is Type.NULL
  448. @property
  449. def IsBool(self):
  450. return self._type is Type.BOOL
  451. @property
  452. def AsBool(self):
  453. if self._type is Type.BOOL:
  454. return bool(_Unpack(U, self._Bytes))
  455. else:
  456. return self.AsInt != 0
  457. def MutateBool(self, value):
  458. """Mutates underlying boolean value bytes in place.
  459. Args:
  460. value: New boolean value.
  461. Returns:
  462. Whether the value was mutated or not.
  463. """
  464. return self.IsBool and \
  465. _Mutate(U, self._buf, value, self._parent_width, BitWidth.W8)
  466. @property
  467. def IsNumeric(self):
  468. return self.IsInt or self.IsFloat
  469. @property
  470. def IsInt(self):
  471. return self._type in (Type.INT, Type.INDIRECT_INT, Type.UINT,
  472. Type.INDIRECT_UINT)
  473. @property
  474. def AsInt(self):
  475. """Returns current reference as integer value."""
  476. if self.IsNull:
  477. return 0
  478. elif self.IsBool:
  479. return int(self.AsBool)
  480. elif self._type is Type.INT:
  481. return _Unpack(I, self._Bytes)
  482. elif self._type is Type.INDIRECT_INT:
  483. return _Unpack(I, self._Indirect()[:self._byte_width])
  484. if self._type is Type.UINT:
  485. return _Unpack(U, self._Bytes)
  486. elif self._type is Type.INDIRECT_UINT:
  487. return _Unpack(U, self._Indirect()[:self._byte_width])
  488. elif self.IsString:
  489. return len(self.AsString)
  490. elif self.IsKey:
  491. return len(self.AsKey)
  492. elif self.IsBlob:
  493. return len(self.AsBlob)
  494. elif self.IsVector:
  495. return len(self.AsVector)
  496. elif self.IsTypedVector:
  497. return len(self.AsTypedVector)
  498. elif self.IsFixedTypedVector:
  499. return len(self.AsFixedTypedVector)
  500. else:
  501. raise self._ConvertError(Type.INT)
  502. def MutateInt(self, value):
  503. """Mutates underlying integer value bytes in place.
  504. Args:
  505. value: New integer value. It must fit to the byte size of the existing
  506. encoded value.
  507. Returns:
  508. Whether the value was mutated or not.
  509. """
  510. if self._type is Type.INT:
  511. return _Mutate(I, self._buf, value, self._parent_width, BitWidth.I(value))
  512. elif self._type is Type.INDIRECT_INT:
  513. return _Mutate(I, self._Indirect(), value, self._byte_width,
  514. BitWidth.I(value))
  515. elif self._type is Type.UINT:
  516. return _Mutate(U, self._buf, value, self._parent_width, BitWidth.U(value))
  517. elif self._type is Type.INDIRECT_UINT:
  518. return _Mutate(U, self._Indirect(), value, self._byte_width,
  519. BitWidth.U(value))
  520. else:
  521. return False
  522. @property
  523. def IsFloat(self):
  524. return self._type in (Type.FLOAT, Type.INDIRECT_FLOAT)
  525. @property
  526. def AsFloat(self):
  527. """Returns current reference as floating point value."""
  528. if self.IsNull:
  529. return 0.0
  530. elif self.IsBool:
  531. return float(self.AsBool)
  532. elif self.IsInt:
  533. return float(self.AsInt)
  534. elif self._type is Type.FLOAT:
  535. return _Unpack(F, self._Bytes)
  536. elif self._type is Type.INDIRECT_FLOAT:
  537. return _Unpack(F, self._Indirect()[:self._byte_width])
  538. elif self.IsString:
  539. return float(self.AsString)
  540. elif self.IsVector:
  541. return float(len(self.AsVector))
  542. elif self.IsTypedVector():
  543. return float(len(self.AsTypedVector))
  544. elif self.IsFixedTypedVector():
  545. return float(len(self.FixedTypedVector))
  546. else:
  547. raise self._ConvertError(Type.FLOAT)
  548. def MutateFloat(self, value):
  549. """Mutates underlying floating point value bytes in place.
  550. Args:
  551. value: New float value. It must fit to the byte size of the existing
  552. encoded value.
  553. Returns:
  554. Whether the value was mutated or not.
  555. """
  556. if self._type is Type.FLOAT:
  557. return _Mutate(F, self._buf, value, self._parent_width,
  558. BitWidth.B(self._parent_width))
  559. elif self._type is Type.INDIRECT_FLOAT:
  560. return _Mutate(F, self._Indirect(), value, self._byte_width,
  561. BitWidth.B(self._byte_width))
  562. else:
  563. return False
  564. @property
  565. def IsKey(self):
  566. return self._type is Type.KEY
  567. @property
  568. def AsKeyBytes(self):
  569. if self.IsKey:
  570. return Key(self._Indirect(), self._byte_width).Bytes
  571. else:
  572. raise self._ConvertError(Type.KEY)
  573. @property
  574. def AsKey(self):
  575. if self.IsKey:
  576. return str(Key(self._Indirect(), self._byte_width))
  577. else:
  578. raise self._ConvertError(Type.KEY)
  579. @property
  580. def IsString(self):
  581. return self._type is Type.STRING
  582. @property
  583. def AsStringBytes(self):
  584. if self.IsString:
  585. return String(self._Indirect(), self._byte_width).Bytes
  586. elif self.IsKey:
  587. return self.AsKeyBytes
  588. else:
  589. raise self._ConvertError(Type.STRING)
  590. @property
  591. def AsString(self):
  592. if self.IsString:
  593. return str(String(self._Indirect(), self._byte_width))
  594. elif self.IsKey:
  595. return self.AsKey
  596. else:
  597. raise self._ConvertError(Type.STRING)
  598. def MutateString(self, value):
  599. return String(self._Indirect(), self._byte_width).Mutate(value)
  600. @property
  601. def IsBlob(self):
  602. return self._type is Type.BLOB
  603. @property
  604. def AsBlob(self):
  605. if self.IsBlob:
  606. return Blob(self._Indirect(), self._byte_width).Bytes
  607. else:
  608. raise self._ConvertError(Type.BLOB)
  609. @property
  610. def IsAnyVector(self):
  611. return self.IsVector or self.IsTypedVector or self.IsFixedTypedVector()
  612. @property
  613. def IsVector(self):
  614. return self._type in (Type.VECTOR, Type.MAP)
  615. @property
  616. def AsVector(self):
  617. if self.IsVector:
  618. return Vector(self._Indirect(), self._byte_width)
  619. else:
  620. raise self._ConvertError(Type.VECTOR)
  621. @property
  622. def IsTypedVector(self):
  623. return Type.IsTypedVector(self._type)
  624. @property
  625. def AsTypedVector(self):
  626. if self.IsTypedVector:
  627. return TypedVector(self._Indirect(), self._byte_width,
  628. Type.ToTypedVectorElementType(self._type))
  629. else:
  630. raise self._ConvertError('TYPED_VECTOR')
  631. @property
  632. def IsFixedTypedVector(self):
  633. return Type.IsFixedTypedVector(self._type)
  634. @property
  635. def AsFixedTypedVector(self):
  636. if self.IsFixedTypedVector:
  637. element_type, size = Type.ToFixedTypedVectorElementType(self._type)
  638. return TypedVector(self._Indirect(), self._byte_width, element_type, size)
  639. else:
  640. raise self._ConvertError('FIXED_TYPED_VECTOR')
  641. @property
  642. def IsMap(self):
  643. return self._type is Type.MAP
  644. @property
  645. def AsMap(self):
  646. if self.IsMap:
  647. return Map(self._Indirect(), self._byte_width)
  648. else:
  649. raise self._ConvertError(Type.MAP)
  650. @property
  651. def Value(self):
  652. """Converts current reference to value of corresponding type.
  653. This is equivalent to calling `AsInt` for integer values, `AsFloat` for
  654. floating point values, etc.
  655. Returns:
  656. Value of corresponding type.
  657. """
  658. if self.IsNull:
  659. return None
  660. elif self.IsBool:
  661. return self.AsBool
  662. elif self.IsInt:
  663. return self.AsInt
  664. elif self.IsFloat:
  665. return self.AsFloat
  666. elif self.IsString:
  667. return self.AsString
  668. elif self.IsKey:
  669. return self.AsKey
  670. elif self.IsBlob:
  671. return self.AsBlob
  672. elif self.IsMap:
  673. return self.AsMap.Value
  674. elif self.IsVector:
  675. return self.AsVector.Value
  676. elif self.IsTypedVector:
  677. return self.AsTypedVector.Value
  678. elif self.IsFixedTypedVector:
  679. return self.AsFixedTypedVector.Value
  680. else:
  681. raise TypeError('cannot convert %r to value' % self)
  682. def _IsIterable(obj):
  683. try:
  684. iter(obj)
  685. return True
  686. except TypeError:
  687. return False
  688. class Value:
  689. """Class to represent given value during the encoding process."""
  690. @staticmethod
  691. def Null():
  692. return Value(0, Type.NULL, BitWidth.W8)
  693. @staticmethod
  694. def Bool(value):
  695. return Value(value, Type.BOOL, BitWidth.W8)
  696. @staticmethod
  697. def Int(value, bit_width):
  698. return Value(value, Type.INT, bit_width)
  699. @staticmethod
  700. def UInt(value, bit_width):
  701. return Value(value, Type.UINT, bit_width)
  702. @staticmethod
  703. def Float(value, bit_width):
  704. return Value(value, Type.FLOAT, bit_width)
  705. @staticmethod
  706. def Key(offset):
  707. return Value(offset, Type.KEY, BitWidth.W8)
  708. def __init__(self, value, type_, min_bit_width):
  709. self._value = value
  710. self._type = type_
  711. # For scalars: of itself, for vector: of its elements, for string: length.
  712. self._min_bit_width = min_bit_width
  713. @property
  714. def Value(self):
  715. return self._value
  716. @property
  717. def Type(self):
  718. return self._type
  719. @property
  720. def MinBitWidth(self):
  721. return self._min_bit_width
  722. def StoredPackedType(self, parent_bit_width=BitWidth.W8):
  723. return Type.Pack(self._type, self.StoredWidth(parent_bit_width))
  724. # We have an absolute offset, but want to store a relative offset
  725. # elem_index elements beyond the current buffer end. Since whether
  726. # the relative offset fits in a certain byte_width depends on
  727. # the size of the elements before it (and their alignment), we have
  728. # to test for each size in turn.
  729. def ElemWidth(self, buf_size, elem_index=0):
  730. if Type.IsInline(self._type):
  731. return self._min_bit_width
  732. for byte_width in 1, 2, 4, 8:
  733. offset_loc = buf_size + _PaddingBytes(buf_size, byte_width) + \
  734. elem_index * byte_width
  735. bit_width = BitWidth.U(offset_loc - self._value)
  736. if byte_width == (1 << bit_width):
  737. return bit_width
  738. raise ValueError('relative offset is too big')
  739. def StoredWidth(self, parent_bit_width=BitWidth.W8):
  740. if Type.IsInline(self._type):
  741. return max(self._min_bit_width, parent_bit_width)
  742. return self._min_bit_width
  743. def __repr__(self):
  744. return 'Value(%s, %s, %s)' % (self._value, self._type, self._min_bit_width)
  745. def __str__(self):
  746. return str(self._value)
  747. def InMap(func):
  748. def wrapper(self, *args, **kwargs):
  749. if isinstance(args[0], str):
  750. self.Key(args[0])
  751. func(self, *args[1:], **kwargs)
  752. else:
  753. func(self, *args, **kwargs)
  754. return wrapper
  755. def InMapForString(func):
  756. def wrapper(self, *args):
  757. if len(args) == 1:
  758. func(self, args[0])
  759. elif len(args) == 2:
  760. self.Key(args[0])
  761. func(self, args[1])
  762. else:
  763. raise ValueError('invalid number of arguments')
  764. return wrapper
  765. class Pool:
  766. """Collection of (data, offset) pairs sorted by data for quick access."""
  767. def __init__(self):
  768. self._pool = [] # sorted list of (data, offset) tuples
  769. def FindOrInsert(self, data, offset):
  770. do = data, offset
  771. index = _BinarySearch(self._pool, do, lambda a, b: a[0] < b[0])
  772. if index != -1:
  773. _, offset = self._pool[index]
  774. return offset
  775. self._pool.insert(index, do)
  776. return None
  777. def Clear(self):
  778. self._pool = []
  779. @property
  780. def Elements(self):
  781. return [data for data, _ in self._pool]
  782. class Builder:
  783. """Helper class to encode structural data into flexbuffers format."""
  784. def __init__(self,
  785. share_strings=False,
  786. share_keys=True,
  787. force_min_bit_width=BitWidth.W8):
  788. self._share_strings = share_strings
  789. self._share_keys = share_keys
  790. self._force_min_bit_width = force_min_bit_width
  791. self._string_pool = Pool()
  792. self._key_pool = Pool()
  793. self._finished = False
  794. self._buf = bytearray()
  795. self._stack = []
  796. def __len__(self):
  797. return len(self._buf)
  798. @property
  799. def StringPool(self):
  800. return self._string_pool
  801. @property
  802. def KeyPool(self):
  803. return self._key_pool
  804. def Clear(self):
  805. self._string_pool.Clear()
  806. self._key_pool.Clear()
  807. self._finished = False
  808. self._buf = bytearray()
  809. self._stack = []
  810. def Finish(self):
  811. """Finishes encoding process and returns underlying buffer."""
  812. if self._finished:
  813. raise RuntimeError('builder has been already finished')
  814. # If you hit this exception, you likely have objects that were never
  815. # included in a parent. You need to have exactly one root to finish a
  816. # buffer. Check your Start/End calls are matched, and all objects are inside
  817. # some other object.
  818. if len(self._stack) != 1:
  819. raise RuntimeError('internal stack size must be one')
  820. value = self._stack[0]
  821. byte_width = self._Align(value.ElemWidth(len(self._buf)))
  822. self._WriteAny(value, byte_width=byte_width) # Root value
  823. self._Write(U, value.StoredPackedType(), byte_width=1) # Root type
  824. self._Write(U, byte_width, byte_width=1) # Root size
  825. self.finished = True
  826. return self._buf
  827. def _ReadKey(self, offset):
  828. key = self._buf[offset:]
  829. return key[:key.find(0)]
  830. def _Align(self, alignment):
  831. byte_width = 1 << alignment
  832. self._buf.extend(b'\x00' * _PaddingBytes(len(self._buf), byte_width))
  833. return byte_width
  834. def _Write(self, fmt, value, byte_width):
  835. self._buf.extend(_Pack(fmt, value, byte_width))
  836. def _WriteVector(self, fmt, values, byte_width):
  837. self._buf.extend(_PackVector(fmt, values, byte_width))
  838. def _WriteOffset(self, offset, byte_width):
  839. relative_offset = len(self._buf) - offset
  840. assert byte_width == 8 or relative_offset < (1 << (8 * byte_width))
  841. self._Write(U, relative_offset, byte_width)
  842. def _WriteAny(self, value, byte_width):
  843. fmt = {
  844. Type.NULL: U, Type.BOOL: U, Type.INT: I, Type.UINT: U, Type.FLOAT: F
  845. }.get(value.Type)
  846. if fmt:
  847. self._Write(fmt, value.Value, byte_width)
  848. else:
  849. self._WriteOffset(value.Value, byte_width)
  850. def _WriteBlob(self, data, append_zero, type_):
  851. bit_width = BitWidth.U(len(data))
  852. byte_width = self._Align(bit_width)
  853. self._Write(U, len(data), byte_width)
  854. loc = len(self._buf)
  855. self._buf.extend(data)
  856. if append_zero:
  857. self._buf.append(0)
  858. self._stack.append(Value(loc, type_, bit_width))
  859. return loc
  860. def _WriteScalarVector(self, element_type, byte_width, elements, fixed):
  861. """Writes scalar vector elements to the underlying buffer."""
  862. bit_width = BitWidth.B(byte_width)
  863. # If you get this exception, you're trying to write a vector with a size
  864. # field that is bigger than the scalars you're trying to write (e.g. a
  865. # byte vector > 255 elements). For such types, write a "blob" instead.
  866. if BitWidth.U(len(elements)) > bit_width:
  867. raise ValueError('too many elements for the given byte_width')
  868. self._Align(bit_width)
  869. if not fixed:
  870. self._Write(U, len(elements), byte_width)
  871. loc = len(self._buf)
  872. fmt = {Type.INT: I, Type.UINT: U, Type.FLOAT: F}.get(element_type)
  873. if not fmt:
  874. raise TypeError('unsupported element_type')
  875. self._WriteVector(fmt, elements, byte_width)
  876. type_ = Type.ToTypedVector(element_type, len(elements) if fixed else 0)
  877. self._stack.append(Value(loc, type_, bit_width))
  878. return loc
  879. def _CreateVector(self, elements, typed, fixed, keys=None):
  880. """Writes vector elements to the underlying buffer."""
  881. length = len(elements)
  882. if fixed and not typed:
  883. raise ValueError('fixed vector must be typed')
  884. # Figure out smallest bit width we can store this vector with.
  885. bit_width = max(self._force_min_bit_width, BitWidth.U(length))
  886. prefix_elems = 1 # Vector size
  887. if keys:
  888. bit_width = max(bit_width, keys.ElemWidth(len(self._buf)))
  889. prefix_elems += 2 # Offset to the keys vector and its byte width.
  890. vector_type = Type.KEY
  891. # Check bit widths and types for all elements.
  892. for i, e in enumerate(elements):
  893. bit_width = max(bit_width, e.ElemWidth(len(self._buf), prefix_elems + i))
  894. if typed:
  895. if i == 0:
  896. vector_type = e.Type
  897. else:
  898. if vector_type != e.Type:
  899. raise RuntimeError('typed vector elements must be of the same type')
  900. if fixed and not Type.IsFixedTypedVectorElementType(vector_type):
  901. raise RuntimeError('must be fixed typed vector element type')
  902. byte_width = self._Align(bit_width)
  903. # Write vector. First the keys width/offset if available, and size.
  904. if keys:
  905. self._WriteOffset(keys.Value, byte_width)
  906. self._Write(U, 1 << keys.MinBitWidth, byte_width)
  907. if not fixed:
  908. self._Write(U, length, byte_width)
  909. # Then the actual data.
  910. loc = len(self._buf)
  911. for e in elements:
  912. self._WriteAny(e, byte_width)
  913. # Then the types.
  914. if not typed:
  915. for e in elements:
  916. self._buf.append(e.StoredPackedType(bit_width))
  917. if keys:
  918. type_ = Type.MAP
  919. else:
  920. if typed:
  921. type_ = Type.ToTypedVector(vector_type, length if fixed else 0)
  922. else:
  923. type_ = Type.VECTOR
  924. return Value(loc, type_, bit_width)
  925. def _PushIndirect(self, value, type_, bit_width):
  926. byte_width = self._Align(bit_width)
  927. loc = len(self._buf)
  928. fmt = {
  929. Type.INDIRECT_INT: I,
  930. Type.INDIRECT_UINT: U,
  931. Type.INDIRECT_FLOAT: F
  932. }[type_]
  933. self._Write(fmt, value, byte_width)
  934. self._stack.append(Value(loc, type_, bit_width))
  935. @InMapForString
  936. def String(self, value):
  937. """Encodes string value."""
  938. reset_to = len(self._buf)
  939. encoded = value.encode('utf-8')
  940. loc = self._WriteBlob(encoded, append_zero=True, type_=Type.STRING)
  941. if self._share_strings:
  942. prev_loc = self._string_pool.FindOrInsert(encoded, loc)
  943. if prev_loc is not None:
  944. del self._buf[reset_to:]
  945. self._stack[-1]._value = loc = prev_loc # pylint: disable=protected-access
  946. return loc
  947. @InMap
  948. def Blob(self, value):
  949. """Encodes binary blob value.
  950. Args:
  951. value: A byte/bytearray value to encode
  952. Returns:
  953. Offset of the encoded value in underlying the byte buffer.
  954. """
  955. return self._WriteBlob(value, append_zero=False, type_=Type.BLOB)
  956. def Key(self, value):
  957. """Encodes key value.
  958. Args:
  959. value: A byte/bytearray/str value to encode. Byte object must not contain
  960. zero bytes. String object must be convertible to ASCII.
  961. Returns:
  962. Offset of the encoded value in the underlying byte buffer.
  963. """
  964. if isinstance(value, (bytes, bytearray)):
  965. encoded = value
  966. else:
  967. encoded = value.encode('ascii')
  968. if 0 in encoded:
  969. raise ValueError('key contains zero byte')
  970. loc = len(self._buf)
  971. self._buf.extend(encoded)
  972. self._buf.append(0)
  973. if self._share_keys:
  974. prev_loc = self._key_pool.FindOrInsert(encoded, loc)
  975. if prev_loc is not None:
  976. del self._buf[loc:]
  977. loc = prev_loc
  978. self._stack.append(Value.Key(loc))
  979. return loc
  980. def Null(self, key=None):
  981. """Encodes None value."""
  982. if key:
  983. self.Key(key)
  984. self._stack.append(Value.Null())
  985. @InMap
  986. def Bool(self, value):
  987. """Encodes boolean value.
  988. Args:
  989. value: A boolean value.
  990. """
  991. self._stack.append(Value.Bool(value))
  992. @InMap
  993. def Int(self, value, byte_width=0):
  994. """Encodes signed integer value.
  995. Args:
  996. value: A signed integer value.
  997. byte_width: Number of bytes to use: 1, 2, 4, or 8.
  998. """
  999. bit_width = BitWidth.I(value) if byte_width == 0 else BitWidth.B(byte_width)
  1000. self._stack.append(Value.Int(value, bit_width))
  1001. @InMap
  1002. def IndirectInt(self, value, byte_width=0):
  1003. """Encodes signed integer value indirectly.
  1004. Args:
  1005. value: A signed integer value.
  1006. byte_width: Number of bytes to use: 1, 2, 4, or 8.
  1007. """
  1008. bit_width = BitWidth.I(value) if byte_width == 0 else BitWidth.B(byte_width)
  1009. self._PushIndirect(value, Type.INDIRECT_INT, bit_width)
  1010. @InMap
  1011. def UInt(self, value, byte_width=0):
  1012. """Encodes unsigned integer value.
  1013. Args:
  1014. value: An unsigned integer value.
  1015. byte_width: Number of bytes to use: 1, 2, 4, or 8.
  1016. """
  1017. bit_width = BitWidth.U(value) if byte_width == 0 else BitWidth.B(byte_width)
  1018. self._stack.append(Value.UInt(value, bit_width))
  1019. @InMap
  1020. def IndirectUInt(self, value, byte_width=0):
  1021. """Encodes unsigned integer value indirectly.
  1022. Args:
  1023. value: An unsigned integer value.
  1024. byte_width: Number of bytes to use: 1, 2, 4, or 8.
  1025. """
  1026. bit_width = BitWidth.U(value) if byte_width == 0 else BitWidth.B(byte_width)
  1027. self._PushIndirect(value, Type.INDIRECT_UINT, bit_width)
  1028. @InMap
  1029. def Float(self, value, byte_width=0):
  1030. """Encodes floating point value.
  1031. Args:
  1032. value: A floating point value.
  1033. byte_width: Number of bytes to use: 4 or 8.
  1034. """
  1035. bit_width = BitWidth.F(value) if byte_width == 0 else BitWidth.B(byte_width)
  1036. self._stack.append(Value.Float(value, bit_width))
  1037. @InMap
  1038. def IndirectFloat(self, value, byte_width=0):
  1039. """Encodes floating point value indirectly.
  1040. Args:
  1041. value: A floating point value.
  1042. byte_width: Number of bytes to use: 4 or 8.
  1043. """
  1044. bit_width = BitWidth.F(value) if byte_width == 0 else BitWidth.B(byte_width)
  1045. self._PushIndirect(value, Type.INDIRECT_FLOAT, bit_width)
  1046. def _StartVector(self):
  1047. """Starts vector construction."""
  1048. return len(self._stack)
  1049. def _EndVector(self, start, typed, fixed):
  1050. """Finishes vector construction by encodung its elements."""
  1051. vec = self._CreateVector(self._stack[start:], typed, fixed)
  1052. del self._stack[start:]
  1053. self._stack.append(vec)
  1054. return vec.Value
  1055. @contextlib.contextmanager
  1056. def Vector(self, key=None):
  1057. if key:
  1058. self.Key(key)
  1059. try:
  1060. start = self._StartVector()
  1061. yield self
  1062. finally:
  1063. self._EndVector(start, typed=False, fixed=False)
  1064. @InMap
  1065. def VectorFromElements(self, elements):
  1066. """Encodes sequence of any elements as a vector.
  1067. Args:
  1068. elements: sequence of elements, they may have different types.
  1069. """
  1070. with self.Vector():
  1071. for e in elements:
  1072. self.Add(e)
  1073. @contextlib.contextmanager
  1074. def TypedVector(self, key=None):
  1075. if key:
  1076. self.Key(key)
  1077. try:
  1078. start = self._StartVector()
  1079. yield self
  1080. finally:
  1081. self._EndVector(start, typed=True, fixed=False)
  1082. @InMap
  1083. def TypedVectorFromElements(self, elements, element_type=None):
  1084. """Encodes sequence of elements of the same type as typed vector.
  1085. Args:
  1086. elements: Sequence of elements, they must be of the same type.
  1087. element_type: Suggested element type. Setting it to None means determining
  1088. correct value automatically based on the given elements.
  1089. """
  1090. if isinstance(elements, array.array):
  1091. if elements.typecode == 'f':
  1092. self._WriteScalarVector(Type.FLOAT, 4, elements, fixed=False)
  1093. elif elements.typecode == 'd':
  1094. self._WriteScalarVector(Type.FLOAT, 8, elements, fixed=False)
  1095. elif elements.typecode in ('b', 'h', 'i', 'l', 'q'):
  1096. self._WriteScalarVector(
  1097. Type.INT, elements.itemsize, elements, fixed=False)
  1098. elif elements.typecode in ('B', 'H', 'I', 'L', 'Q'):
  1099. self._WriteScalarVector(
  1100. Type.UINT, elements.itemsize, elements, fixed=False)
  1101. else:
  1102. raise ValueError('unsupported array typecode: %s' % elements.typecode)
  1103. else:
  1104. add = self.Add if element_type is None else self.Adder(element_type)
  1105. with self.TypedVector():
  1106. for e in elements:
  1107. add(e)
  1108. @InMap
  1109. def FixedTypedVectorFromElements(self,
  1110. elements,
  1111. element_type=None,
  1112. byte_width=0):
  1113. """Encodes sequence of elements of the same type as fixed typed vector.
  1114. Args:
  1115. elements: Sequence of elements, they must be of the same type. Allowed
  1116. types are `Type.INT`, `Type.UINT`, `Type.FLOAT`. Allowed number of
  1117. elements are 2, 3, or 4.
  1118. element_type: Suggested element type. Setting it to None means determining
  1119. correct value automatically based on the given elements.
  1120. byte_width: Number of bytes to use per element. For `Type.INT` and
  1121. `Type.UINT`: 1, 2, 4, or 8. For `Type.FLOAT`: 4 or 8. Setting it to 0
  1122. means determining correct value automatically based on the given
  1123. elements.
  1124. """
  1125. if not 2 <= len(elements) <= 4:
  1126. raise ValueError('only 2, 3, or 4 elements are supported')
  1127. types = {type(e) for e in elements}
  1128. if len(types) != 1:
  1129. raise TypeError('all elements must be of the same type')
  1130. type_, = types
  1131. if element_type is None:
  1132. element_type = {int: Type.INT, float: Type.FLOAT}.get(type_)
  1133. if not element_type:
  1134. raise TypeError('unsupported element_type: %s' % type_)
  1135. if byte_width == 0:
  1136. width = {
  1137. Type.UINT: BitWidth.U,
  1138. Type.INT: BitWidth.I,
  1139. Type.FLOAT: BitWidth.F
  1140. }[element_type]
  1141. byte_width = 1 << max(width(e) for e in elements)
  1142. self._WriteScalarVector(element_type, byte_width, elements, fixed=True)
  1143. def _StartMap(self):
  1144. """Starts map construction."""
  1145. return len(self._stack)
  1146. def _EndMap(self, start):
  1147. """Finishes map construction by encodung its elements."""
  1148. # Interleaved keys and values on the stack.
  1149. stack = self._stack[start:]
  1150. if len(stack) % 2 != 0:
  1151. raise RuntimeError('must be even number of keys and values')
  1152. for key in stack[::2]:
  1153. if key.Type is not Type.KEY:
  1154. raise RuntimeError('all map keys must be of %s type' % Type.KEY)
  1155. pairs = zip(stack[::2], stack[1::2]) # [(key, value), ...]
  1156. pairs = sorted(pairs, key=lambda pair: self._ReadKey(pair[0].Value))
  1157. del self._stack[start:]
  1158. for pair in pairs:
  1159. self._stack.extend(pair)
  1160. keys = self._CreateVector(self._stack[start::2], typed=True, fixed=False)
  1161. values = self._CreateVector(
  1162. self._stack[start + 1::2], typed=False, fixed=False, keys=keys)
  1163. del self._stack[start:]
  1164. self._stack.append(values)
  1165. return values.Value
  1166. @contextlib.contextmanager
  1167. def Map(self, key=None):
  1168. if key:
  1169. self.Key(key)
  1170. try:
  1171. start = self._StartMap()
  1172. yield self
  1173. finally:
  1174. self._EndMap(start)
  1175. def MapFromElements(self, elements):
  1176. start = self._StartMap()
  1177. for k, v in elements.items():
  1178. self.Key(k)
  1179. self.Add(v)
  1180. self._EndMap(start)
  1181. def Adder(self, type_):
  1182. return {
  1183. Type.BOOL: self.Bool,
  1184. Type.INT: self.Int,
  1185. Type.INDIRECT_INT: self.IndirectInt,
  1186. Type.UINT: self.UInt,
  1187. Type.INDIRECT_UINT: self.IndirectUInt,
  1188. Type.FLOAT: self.Float,
  1189. Type.INDIRECT_FLOAT: self.IndirectFloat,
  1190. Type.KEY: self.Key,
  1191. Type.BLOB: self.Blob,
  1192. Type.STRING: self.String,
  1193. }[type_]
  1194. @InMapForString
  1195. def Add(self, value):
  1196. """Encodes value of any supported type."""
  1197. if value is None:
  1198. self.Null()
  1199. elif isinstance(value, bool):
  1200. self.Bool(value)
  1201. elif isinstance(value, int):
  1202. self.Int(value)
  1203. elif isinstance(value, float):
  1204. self.Float(value)
  1205. elif isinstance(value, str):
  1206. self.String(value)
  1207. elif isinstance(value, (bytes, bytearray)):
  1208. self.Blob(value)
  1209. elif isinstance(value, dict):
  1210. with self.Map():
  1211. for k, v in value.items():
  1212. self.Key(k)
  1213. self.Add(v)
  1214. elif isinstance(value, array.array):
  1215. self.TypedVectorFromElements(value)
  1216. elif _IsIterable(value):
  1217. self.VectorFromElements(value)
  1218. else:
  1219. raise TypeError('unsupported python type: %s' % type(value))
  1220. @property
  1221. def LastValue(self):
  1222. return self._stack[-1]
  1223. @InMap
  1224. def ReuseValue(self, value):
  1225. self._stack.append(value)
  1226. def GetRoot(buf):
  1227. """Returns root `Ref` object for the given buffer."""
  1228. if len(buf) < 3:
  1229. raise ValueError('buffer is too small')
  1230. byte_width = buf[-1]
  1231. return Ref.PackedType(
  1232. Buf(buf, -(2 + byte_width)), byte_width, packed_type=buf[-2])
  1233. def Dumps(obj):
  1234. """Returns bytearray with the encoded python object."""
  1235. fbb = Builder()
  1236. fbb.Add(obj)
  1237. return fbb.Finish()
  1238. def Loads(buf):
  1239. """Returns python object decoded from the buffer."""
  1240. return GetRoot(buf).Value