|
|
|
@ -385,6 +385,41 @@ def isInt(any): |
|
|
|
return True |
|
|
|
except: |
|
|
|
return False |
|
|
|
|
|
|
|
def _skip_group(buf, i, group_field, _depth=0, _max_depth=_MAX_NESTING_DEPTH): |
|
|
|
"""Пропускает все поля группы, начиная с позиции i, и возвращает новую позицию после end group.""" |
|
|
|
if _depth > _max_depth: |
|
|
|
raise ValueError("group nesting too deep") |
|
|
|
b = memoryview(buf).toreadonly() if not isinstance(buf, bytearray) else buf |
|
|
|
n = len(b) |
|
|
|
while i < n: |
|
|
|
key, i = _read_varint(b, i) |
|
|
|
field = key >> 3 |
|
|
|
wt = key & 7 |
|
|
|
|
|
|
|
if wt == 4: # end group |
|
|
|
if field == group_field: |
|
|
|
return i # группа закрыта, возвращаем позицию после ключа end group |
|
|
|
else: |
|
|
|
raise ValueError(f"mismatched end group: expected {group_field}, got {field}") |
|
|
|
|
|
|
|
# Пропускаем содержимое в зависимости от wire type |
|
|
|
if wt == 0: # varint |
|
|
|
_, i = _read_varint(b, i) |
|
|
|
elif wt == 1: # 64-bit |
|
|
|
i += 8 |
|
|
|
elif wt == 2: # length-delimited |
|
|
|
length, i = _read_varint(b, i) |
|
|
|
if i + length > n: |
|
|
|
raise ValueError("truncated length-delimited inside group") |
|
|
|
i += length |
|
|
|
elif wt == 3: # start group (вложенная) |
|
|
|
i = _skip_group(b, i, field, _depth+1, _max_depth) |
|
|
|
elif wt == 5: # 32-bit |
|
|
|
i += 4 |
|
|
|
else: |
|
|
|
raise ValueError(f"unsupported wire type {wt} inside group") |
|
|
|
raise ValueError("group not terminated") |
|
|
|
|
|
|
|
def decode(buf, schema=None, _depth=0, _max_depth=_MAX_NESTING_DEPTH): |
|
|
|
if _depth > _max_depth: |
|
|
|
@ -406,7 +441,12 @@ def decode(buf, schema=None, _depth=0, _max_depth=_MAX_NESTING_DEPTH): |
|
|
|
spec = ns["fields"].get(field) |
|
|
|
|
|
|
|
if wt == 0: |
|
|
|
v, i = _read_varint(b, i) |
|
|
|
try: |
|
|
|
v, i = _read_varint(b, i) |
|
|
|
except Exception as rve: |
|
|
|
print("key=",key, "i=",i, "field=",field, "wt=", wt,"spec=",spec, "ns-fields=", ns["fields"]) |
|
|
|
raise rve |
|
|
|
|
|
|
|
if spec: |
|
|
|
t = spec.get("type") |
|
|
|
if t in {"sint", "sint64"}: |
|
|
|
@ -456,6 +496,13 @@ def decode(buf, schema=None, _depth=0, _max_depth=_MAX_NESTING_DEPTH): |
|
|
|
v = chunk |
|
|
|
else: |
|
|
|
v = chunk |
|
|
|
elif wt == 3: |
|
|
|
# Пропускаем всю группу, данные не сохраняем |
|
|
|
i = _skip_group(b, i, field, _depth, _max_depth) |
|
|
|
continue # ничего не добавляем в out |
|
|
|
elif wt == 4: |
|
|
|
# Если мы здесь, значит end group встречен не вовремя — ошибка |
|
|
|
raise ValueError("unexpected end group") |
|
|
|
elif wt == 5: |
|
|
|
v, i = _read_fixed32(b, i) |
|
|
|
if spec: |
|
|
|
|