from codecs import getencoder
from collections import namedtuple
from collections import OrderedDict
+from copy import copy
from datetime import datetime
from math import ceil
from os import environ
class ASN1Error(ValueError):
pass
+
class DecodeError(ASN1Error):
def __init__(self, msg="", klass=None, decode_path=(), offset=0):
"""
decode_path=(),
ctx=None,
tag_only=False,
+ _ctx_immutable=True,
):
"""Decode the data
:param tag_only: decode only the tag, without length and contents
(used only in Choice and Set structures, trying to
determine if tag satisfies the scheme)
+ :param _ctx_immutable: do we need to copy ``ctx`` before using it
:returns: (Obj, remaining data)
"""
if ctx is None:
ctx = {}
+ elif _ctx_immutable:
+ ctx = copy(ctx)
tlv = memoryview(data)
if self._expl is None:
result = self._decode(
decode_path=sub_decode_path,
leavemm=True,
ctx=ctx,
+ _ctx_immutable=False,
)
except TagMismatch:
raise DecodeError(
decode_path=sub_decode_path,
leavemm=True,
ctx=ctx,
+ _ctx_immutable=False,
)
except TagMismatch:
raise DecodeError(
decode_path=sub_decode_path,
ctx=ctx,
tag_only=True,
+ _ctx_immutable=False,
)
except TagMismatch:
continue
leavemm=True,
decode_path=sub_decode_path,
ctx=ctx,
+ _ctx_immutable=False,
)
obj = self.__class__(
schema=self.specs,
decode_path=decode_path + (str(chunk_i),),
leavemm=True,
ctx=ctx,
+ _ctx_immutable=False,
)
vlen += chunk.tlvlen
sub_offset += chunk.tlvlen
leavemm=True,
decode_path=sub_decode_path,
ctx=ctx,
+ _ctx_immutable=False,
)
except TagMismatch:
if spec.optional:
leavemm=True,
decode_path=sub_sub_decode_path,
ctx=ctx,
+ _ctx_immutable=False,
)
if len(defined_tail) > 0:
raise DecodeError(
leavemm=True,
decode_path=sub_decode_path + (DecodePathDefBy(defined_by),),
ctx=ctx,
+ _ctx_immutable=False,
)
if len(defined_tail) > 0:
raise DecodeError(
decode_path=sub_decode_path,
ctx=ctx,
tag_only=True,
+ _ctx_immutable=False,
)
except TagMismatch:
continue
leavemm=True,
decode_path=sub_decode_path,
ctx=ctx,
+ _ctx_immutable=False,
)
value_len = value.fulllen
if value_prev.tobytes() > v[:value_len].tobytes():
leavemm=True,
decode_path=sub_decode_path,
ctx=ctx,
+ _ctx_immutable=False,
)
value_len = value.fulllen
if ordering_check: