codekingpro/portable-devtools
114k
1# This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild2 3import kaitaistruct4from kaitaistruct import KaitaiStream, KaitaiStruct5from enum import Enum6 7 8if getattr(kaitaistruct, 'API_VERSION', (0, 9)) < (0, 9):9 raise Exception("Incompatible Kaitai Struct Python API: 0.9 or later is required, but you have %s" % (kaitaistruct.__version__))10 11from . import vlq_base128_le12class GoogleProtobuf(KaitaiStruct):13 """Google Protocol Buffers (AKA protobuf) is a popular data14 serialization scheme used for communication protocols, data storage,15 etc. There are implementations are available for almost every16 popular language. The focus points of this scheme are brevity (data17 is encoded in a very size-efficient manner) and extensibility (one18 can add keys to the structure, while keeping it readable in previous19 version of software).20 21 Protobuf uses semi-self-describing encoding scheme for its22 messages. It means that it is possible to parse overall structure of23 the message (skipping over fields one can't understand), but to24 fully understand the message, one needs a protocol definition file25 (`.proto`). To be specific:26 27 * "Keys" in key-value pairs provided in the message are identified28 only with an integer "field tag". `.proto` file provides info on29 which symbolic field names these field tags map to.30 * "Keys" also provide something called "wire type". It's not a data31 type in its common sense (i.e. you can't, for example, distinguish32 `sint32` vs `uint32` vs some enum, or `string` from `bytes`), but33 it's enough information to determine how many bytes to34 parse. Interpretation of the value should be done according to the35 type specified in `.proto` file.36 * There's no direct information on which fields are optional /37 required, which fields may be repeated or constitute a map, what38 restrictions are placed on fields usage in a single message, what39 are the fields' default values, etc, etc.40 41 .. seealso::42 Source - https://developers.google.com/protocol-buffers/docs/encoding43 """44 def __init__(self, _io, _parent=None, _root=None):45 self._io = _io46 self._parent = _parent47 self._root = _root if _root else self48 self._read()49 50 def _read(self):51 self.pairs = []52 i = 053 while not self._io.is_eof():54 self.pairs.append(GoogleProtobuf.Pair(self._io, self, self._root))55 i += 156 57 58 class Pair(KaitaiStruct):59 """Key-value pair."""60 61 class WireTypes(Enum):62 varint = 063 bit_64 = 164 len_delimited = 265 group_start = 366 group_end = 467 bit_32 = 568 def __init__(self, _io, _parent=None, _root=None):69 self._io = _io70 self._parent = _parent71 self._root = _root if _root else self72 self._read()73 74 def _read(self):75 self.key = vlq_base128_le.VlqBase128Le(self._io)76 _on = self.wire_type77 if _on == GoogleProtobuf.Pair.WireTypes.varint:78 self.value = vlq_base128_le.VlqBase128Le(self._io)79 elif _on == GoogleProtobuf.Pair.WireTypes.len_delimited:80 self.value = GoogleProtobuf.DelimitedBytes(self._io, self, self._root)81 elif _on == GoogleProtobuf.Pair.WireTypes.bit_64:82 self.value = self._io.read_u8le()83 elif _on == GoogleProtobuf.Pair.WireTypes.bit_32:84 self.value = self._io.read_u4le()85 86 @property87 def wire_type(self):88 """"Wire type" is a part of the "key" that carries enough89 information to parse value from the wire, i.e. read correct90 amount of bytes, but there's not enough informaton to91 interprete in unambiguously. For example, one can't clearly92 distinguish 64-bit fixed-sized integers from 64-bit floats,93 signed zigzag-encoded varints from regular unsigned varints,94 arbitrary bytes from UTF-8 encoded strings, etc.95 """96 if hasattr(self, '_m_wire_type'):97 return self._m_wire_type98 99 self._m_wire_type = KaitaiStream.resolve_enum(GoogleProtobuf.Pair.WireTypes, (self.key.value & 7))100 return getattr(self, '_m_wire_type', None)101 102 @property103 def field_tag(self):104 """Identifies a field of protocol. One can look up symbolic105 field name in a `.proto` file by this field tag.106 """107 if hasattr(self, '_m_field_tag'):108 return self._m_field_tag109 110 self._m_field_tag = (self.key.value >> 3)111 return getattr(self, '_m_field_tag', None)112 113 114 class DelimitedBytes(KaitaiStruct):115 def __init__(self, _io, _parent=None, _root=None):116 self._io = _io117 self._parent = _parent118 self._root = _root if _root else self119 self._read()120 121 def _read(self):122 self.len = vlq_base128_le.VlqBase128Le(self._io)123 self.body = self._io.read_bytes(self.len.value)124 125 126 127 