|
12 | 12 | # See the License for the specific language governing permissions and
|
13 | 13 | # limitations under the License.
|
14 | 14 |
|
| 15 | +import base64 |
15 | 16 | import collections.abc
|
16 | 17 | import datetime
|
17 | 18 | import math
|
| 19 | +import struct |
18 | 20 | import traceback
|
19 | 21 | from pathlib import Path
|
20 | 22 | from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
@@ -260,6 +262,56 @@ def parse_value(value: Any, refs: Optional[Dict[int, Any]] = None) -> Any:
|
260 | 262 |
|
261 | 263 | if "b" in value:
|
262 | 264 | return value["b"]
|
| 265 | + |
| 266 | + if "ta" in value: |
| 267 | + encoded_bytes = value["ta"]["b"] |
| 268 | + decoded_bytes = base64.b64decode(encoded_bytes) |
| 269 | + array_type = value["ta"]["k"] |
| 270 | + if array_type == "i8": |
| 271 | + word_size = 1 |
| 272 | + fmt = "b" |
| 273 | + elif array_type == "ui8" or array_type == "ui8c": |
| 274 | + word_size = 1 |
| 275 | + fmt = "B" |
| 276 | + elif array_type == "i16": |
| 277 | + word_size = 2 |
| 278 | + fmt = "h" |
| 279 | + elif array_type == "ui16": |
| 280 | + word_size = 2 |
| 281 | + fmt = "H" |
| 282 | + elif array_type == "i32": |
| 283 | + word_size = 4 |
| 284 | + fmt = "i" |
| 285 | + elif array_type == "ui32": |
| 286 | + word_size = 4 |
| 287 | + fmt = "I" |
| 288 | + elif array_type == "f32": |
| 289 | + word_size = 4 |
| 290 | + fmt = "f" |
| 291 | + elif array_type == "f64": |
| 292 | + word_size = 8 |
| 293 | + fmt = "d" |
| 294 | + elif array_type == "bi64": |
| 295 | + word_size = 8 |
| 296 | + fmt = "q" |
| 297 | + elif array_type == "bui64": |
| 298 | + word_size = 8 |
| 299 | + fmt = "Q" |
| 300 | + else: |
| 301 | + raise ValueError(f"Unsupported array type: {array_type}") |
| 302 | + |
| 303 | + byte_len = len(decoded_bytes) |
| 304 | + if byte_len % word_size != 0: |
| 305 | + raise ValueError( |
| 306 | + f"Decoded bytes length {byte_len} is not a multiple of word size {word_size}" |
| 307 | + ) |
| 308 | + |
| 309 | + if byte_len == 0: |
| 310 | + return [] |
| 311 | + array_len = byte_len // word_size |
| 312 | + # "<" denotes little-endian |
| 313 | + format_string = f"<{array_len}{fmt}" |
| 314 | + return list(struct.unpack(format_string, decoded_bytes)) |
263 | 315 | return value
|
264 | 316 |
|
265 | 317 |
|
|
0 commit comments