def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, tlen, lv = tag_strip(tlv)
+ except DecodeError as err:
+ raise err.__class__(
+ msg=err.msg,
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ try:
l, llen, v = len_decode(lv)
+ except LenIndefiniteForm as err:
+ if not ctx.get("bered", False):
+ raise err.__class__(
+ msg=err.msg,
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ llen, vlen, v = 1, 0, lv[1:]
+ sub_offset = offset + tlen + llen
+ chunk_i = 0
+ while True:
+ if v[:EOC_LEN].tobytes() == EOC:
+ tlvlen = tlen + llen + vlen + EOC_LEN
+ obj = self.__class__(
+ value=tlv[:tlvlen].tobytes(),
+ expl=self._expl,
+ optional=self.optional,
+ _decoded=(offset, 0, tlvlen),
+ )
+ obj.bered = True
+ obj.tag = t
+ return obj, v[EOC_LEN:]
+ else:
+ chunk, v = Any().decode(
+ v,
+ offset=sub_offset,
+ decode_path=decode_path + (str(chunk_i),),
+ leavemm=True,
+ ctx=ctx,
+ )
+ vlen += chunk.tlvlen
+ sub_offset += chunk.tlvlen
+ chunk_i += 1
except DecodeError as err:
raise err.__class__(
msg=err.msg,
)
if tag_only:
return
+ eoc_expected = False
try:
l, llen, v = len_decode(lv)
+ except LenIndefiniteForm as err:
+ if not ctx.get("bered", False):
+ raise err.__class__(
+ msg=err.msg,
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ l, llen, v = 0, 1, lv[1:]
+ eoc_expected = True
except DecodeError as err:
raise err.__class__(
msg=err.msg,
decode_path=decode_path,
offset=offset,
)
- v, tail = v[:l], v[l:]
+ if not eoc_expected:
+ v, tail = v[:l], v[l:]
+ vlen = 0
sub_offset = offset + tlen + llen
values = {}
for name, spec in self.specs.items():
- if len(v) == 0 and spec.optional:
+ if spec.optional and (
+ (eoc_expected and v[:EOC_LEN].tobytes() == EOC) or
+ len(v) == 0
+ ):
continue
sub_decode_path = decode_path + (name,)
try:
)
value.defined = (defined_by, defined_value)
- sub_offset += (value.expl_tlvlen if value.expled else value.tlvlen)
+ value_len = value.expl_tlvlen if value.expled else value.tlvlen
+ vlen += value_len
+ sub_offset += value_len
v = v_tail
if spec.default is not None and value == spec.default:
if ctx.get("strict_default_existence", False):
abs_decode_path(sub_decode_path[:-1], rel_path),
(value, defined),
))
- if len(v) > 0:
+ if eoc_expected:
+ if v[:EOC_LEN].tobytes() != EOC:
+ raise DecodeError(
+ "no EOC",
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ tail = v[EOC_LEN:]
+ vlen += EOC_LEN
+ elif len(v) > 0:
raise DecodeError(
"remaining data",
klass=self.__class__,
expl=self._expl,
default=self.default,
optional=self.optional,
- _decoded=(offset, llen, l),
+ _decoded=(offset, llen, vlen),
)
obj._value = values
+ if eoc_expected:
+ obj.bered = True
return obj, tail
def __repr__(self):
)
if tag_only:
return
+ eoc_expected = False
try:
l, llen, v = len_decode(lv)
+ except LenIndefiniteForm as err:
+ if not ctx.get("bered", False):
+ raise err.__class__(
+ msg=err.msg,
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ l, llen, v = 0, 1, lv[1:]
+ eoc_expected = True
except DecodeError as err:
raise err.__class__(
msg=err.msg,
klass=self.__class__,
offset=offset,
)
- v, tail = v[:l], v[l:]
+ if not eoc_expected:
+ v, tail = v[:l], v[l:]
+ vlen = 0
sub_offset = offset + tlen + llen
values = {}
specs_items = self.specs.items
while len(v) > 0:
+ if eoc_expected and v[:EOC_LEN].tobytes() == EOC:
+ break
for name, spec in specs_items():
sub_decode_path = decode_path + (name,)
try:
decode_path=sub_decode_path,
ctx=ctx,
)
- sub_offset += (
- value.expl_tlvlen if value.expled else value.tlvlen
- )
+ value_len = value.expl_tlvlen if value.expled else value.tlvlen
+ sub_offset += value_len
+ vlen += value_len
v = v_tail
if spec.default is None or value != spec.default: # pragma: no cover
# SeqMixing.test_encoded_default_accepted covers that place
expl=self._expl,
default=self.default,
optional=self.optional,
- _decoded=(offset, llen, l),
+ _decoded=(offset, llen, vlen + (EOC_LEN if eoc_expected else 0)),
)
obj._value = values
if not obj.ready:
decode_path=decode_path,
offset=offset,
)
+ if eoc_expected:
+ obj.bered = True
+ tail = v[EOC_LEN:]
return obj, tail
)
if tag_only:
return
+ eoc_expected = False
try:
l, llen, v = len_decode(lv)
+ except LenIndefiniteForm as err:
+ if not ctx.get("bered", False):
+ raise err.__class__(
+ msg=err.msg,
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ l, llen, v = 0, 1, lv[1:]
+ eoc_expected = True
except DecodeError as err:
raise err.__class__(
msg=err.msg,
decode_path=decode_path,
offset=offset,
)
- v, tail = v[:l], v[l:]
+ if not eoc_expected:
+ v, tail = v[:l], v[l:]
+ vlen = 0
sub_offset = offset + tlen + llen
_value = []
spec = self.spec
while len(v) > 0:
+ if eoc_expected and v[:EOC_LEN].tobytes() == EOC:
+ break
value, v_tail = spec.decode(
v,
sub_offset,
decode_path=decode_path + (str(len(_value)),),
ctx=ctx,
)
- sub_offset += (value.expl_tlvlen if value.expled else value.tlvlen)
+ value_len = value.expl_tlvlen if value.expled else value.tlvlen
+ sub_offset += value_len
+ vlen += value_len
v = v_tail
_value.append(value)
obj = self.__class__(
expl=self._expl,
default=self.default,
optional=self.optional,
- _decoded=(offset, llen, l),
+ _decoded=(offset, llen, vlen),
)
+ if eoc_expected:
+ obj.bered = True
+ tail = v[EOC_LEN:]
return obj, tail
def __repr__(self):
pprinter = partial(pprint, big_blobs=True)
else:
schema, pprinter = generic_decoder()
- obj, tail = schema().decode(
- der,
- ctx=(
- None if args.defines_by_path is None else
- {"defines_by_path": obj_by_path(args.defines_by_path)}
- ),
- )
+ ctx = {"bered": True}
+ if args.defines_by_path is not None:
+ ctx["defines_by_path"] = obj_by_path(args.defines_by_path)
+ obj, tail = schema().decode(der, ctx=ctx)
print(pprinter(
obj,
oids=oids,