- def __repr__(self):
- return pp_console_row(next(self.pps()))
-
- def pps(self, decode_path=()):
- yield _pp(
- asn1_type_name=self.asn1_type_name,
- obj_name=self.__class__.__name__,
- decode_path=decode_path,
- value=("%d bytes" % len(self._value)) if self.ready else None,
- blob=self._value if self.ready else None,
- optional=self.optional,
- default=self == self.default,
- impl=None if self.tag == self.tag_default else tag_decode(self.tag),
- expl=None if self._expl is None else tag_decode(self._expl),
- offset=self.offset,
- tlen=self.tlen,
- llen=self.llen,
- vlen=self.vlen,
- expl_offset=self.expl_offset if self.expled else None,
- expl_tlen=self.expl_tlen if self.expled else None,
- expl_llen=self.expl_llen if self.expled else None,
- expl_vlen=self.expl_vlen if self.expled else None,
- )
- defined_by, defined = self.defined or (None, None)
- if defined_by is not None:
- yield defined.pps(
+ 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,
+ )
+ if t == self.tag:
+ if tag_only:
+ return
+ return self._decode_chunk(lv, offset, decode_path, ctx)
+ if t == self.tag_constructed:
+ if not ctx.get("bered", False):
+ raise DecodeError(
+ "unallowed BER constructed encoding",
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ if tag_only:
+ return
+ lenindef = False
+ try:
+ l, llen, v = len_decode(lv)
+ except LenIndefForm:
+ llen, l, v = 1, 0, lv[1:]
+ lenindef = True
+ except DecodeError as err:
+ raise err.__class__(
+ msg=err.msg,
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ if l > len(v):
+ raise NotEnoughData(
+ "encoded length is longer than data",
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ chunks = []
+ sub_offset = offset + tlen + llen
+ vlen = 0
+ while True:
+ if lenindef:
+ if v[:EOC_LEN].tobytes() == EOC:
+ break
+ else:
+ if vlen == l:
+ break
+ if vlen > l:
+ raise DecodeError(
+ "chunk out of bounds",
+ klass=self.__class__,
+ decode_path=decode_path + (str(len(chunks) - 1),),
+ offset=chunks[-1].offset,
+ )
+ sub_decode_path = decode_path + (str(len(chunks)),)
+ try:
+ chunk, v_tail = OctetString().decode(
+ v,
+ offset=sub_offset,
+ decode_path=sub_decode_path,
+ leavemm=True,
+ ctx=ctx,
+ _ctx_immutable=False,
+ )
+ except TagMismatch:
+ raise DecodeError(
+ "expected OctetString encoded chunk",
+ klass=self.__class__,
+ decode_path=sub_decode_path,
+ offset=sub_offset,
+ )
+ chunks.append(chunk)
+ sub_offset += chunk.tlvlen
+ vlen += chunk.tlvlen
+ v = v_tail
+ try:
+ obj = self.__class__(
+ value=b"".join(bytes(chunk) for chunk in chunks),
+ bounds=(self._bound_min, self._bound_max),
+ impl=self.tag,
+ expl=self._expl,
+ default=self.default,
+ optional=self.optional,
+ _decoded=(offset, llen, vlen + (EOC_LEN if lenindef else 0)),
+ )
+ except DecodeError as err:
+ raise DecodeError(
+ msg=err.msg,
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ except BoundsError as err:
+ raise DecodeError(
+ msg=str(err),
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+ obj.lenindef = lenindef
+ obj.ber_encoded = True
+ return obj, (v[EOC_LEN:] if lenindef else v)
+ raise TagMismatch(
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
+ )
+
+ def __repr__(self):
+ return pp_console_row(next(self.pps()))
+
+ def pps(self, decode_path=()):
+ yield _pp(
+ obj=self,
+ asn1_type_name=self.asn1_type_name,
+ obj_name=self.__class__.__name__,
+ decode_path=decode_path,
+ value=("%d bytes" % len(self._value)) if self.ready else None,
+ blob=self._value if self.ready else None,
+ optional=self.optional,
+ default=self == self.default,
+ impl=None if self.tag == self.tag_default else tag_decode(self.tag),
+ expl=None if self._expl is None else tag_decode(self._expl),
+ offset=self.offset,
+ tlen=self.tlen,
+ llen=self.llen,
+ vlen=self.vlen,
+ expl_offset=self.expl_offset if self.expled else None,
+ expl_tlen=self.expl_tlen if self.expled else None,
+ expl_llen=self.expl_llen if self.expled else None,
+ expl_vlen=self.expl_vlen if self.expled else None,
+ expl_lenindef=self.expl_lenindef,
+ lenindef=self.lenindef,
+ ber_encoded=self.ber_encoded,
+ bered=self.bered,
+ )
+ defined_by, defined = self.defined or (None, None)
+ if defined_by is not None:
+ yield defined.pps(