Decode a TLV-encoded value from binary data. Args: data: Binary data to decode offset: Starting offset in the data Returns: tuple: (decoded_value, new_offset) Raises: DirtyProtocolError: If data is malformed or trunc
(data: bytes, offset: int = 0)
| 126 | |
| 127 | @staticmethod |
| 128 | def decode(data: bytes, offset: int = 0) -> tuple: class="cm"># pylint: disable=too-many-return-statements |
| 129 | class="st">""" |
| 130 | Decode a TLV-encoded value from binary data. |
| 131 | |
| 132 | Args: |
| 133 | data: Binary data to decode |
| 134 | offset: Starting offset in the data |
| 135 | |
| 136 | Returns: |
| 137 | tuple: (decoded_value, new_offset) |
| 138 | |
| 139 | Raises: |
| 140 | DirtyProtocolError: If data is malformed or truncated |
| 141 | class="st">""" |
| 142 | if offset >= len(data): |
| 143 | raise DirtyProtocolError( |
| 144 | class="st">"Truncated TLV data: no type byte", |
| 145 | raw_data=data[offset:offset + 20] |
| 146 | ) |
| 147 | |
| 148 | type_code = data[offset] |
| 149 | offset += 1 |
| 150 | |
| 151 | if type_code == TYPE_NONE: |
| 152 | return None, offset |
| 153 | |
| 154 | if type_code == TYPE_BOOL: |
| 155 | if offset >= len(data): |
| 156 | raise DirtyProtocolError( |
| 157 | class="st">"Truncated TLV data: missing bool value", |
| 158 | raw_data=data[offset - 1:offset + 20] |
| 159 | ) |
| 160 | value = data[offset] != 0x00 |
| 161 | return value, offset + 1 |
| 162 | |
| 163 | if type_code == TYPE_INT64: |
| 164 | if offset + 8 > len(data): |
| 165 | raise DirtyProtocolError( |
| 166 | class="st">"Truncated TLV data: incomplete int64", |
| 167 | raw_data=data[offset - 1:offset + 20] |
| 168 | ) |
| 169 | value = struct.unpack(class="st">">q", data[offset:offset + 8])[0] |
| 170 | return value, offset + 8 |
| 171 | |
| 172 | if type_code == TYPE_FLOAT64: |
| 173 | if offset + 8 > len(data): |
| 174 | raise DirtyProtocolError( |
| 175 | class="st">"Truncated TLV data: incomplete float64", |
| 176 | raw_data=data[offset - 1:offset + 20] |
| 177 | ) |
| 178 | value = struct.unpack(class="st">">d", data[offset:offset + 8])[0] |
| 179 | return value, offset + 8 |
| 180 | |
| 181 | if type_code == TYPE_BYTES: |
| 182 | if offset + 4 > len(data): |
| 183 | raise DirtyProtocolError( |
| 184 | class="st">"Truncated TLV data: incomplete bytes length", |
| 185 | raw_data=data[offset - 1:offset + 20] |