diff options
author | Ilya Etingof <etingof@gmail.com> | 2017-04-21 01:09:10 +0200 |
---|---|---|
committer | Ilya Etingof <etingof@gmail.com> | 2017-04-21 01:09:10 +0200 |
commit | 6fb2b5ddc59ac08649bb5a68a2f82e59f165b04d (patch) | |
tree | 5f70e65a2d98f9e6a0f501ab65e310a1ad6f4910 | |
parent | 2d92acee6fc8b581b39ba5bca5fd370c0fbe71af (diff) | |
download | pyasn1-git-6fb2b5ddc59ac08649bb5a68a2f82e59f165b04d.tar.gz |
ANY DEFINED BY decoding implemented
-rw-r--r-- | CHANGES.rst | 1 | ||||
-rw-r--r-- | pyasn1/codec/ber/decoder.py | 13 | ||||
-rw-r--r-- | pyasn1/type/namedtype.py | 28 |
3 files changed, 41 insertions, 1 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 56f3fed..ce97e34 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,7 @@ Revision 0.2.4, released XX-03-2017 ----------------------------------- +- ANY DEFINED BY clause support implemented - ASN.1 types initialization refactored to minimize the use of relatively expensive isNoValue() call - Lazily pre-populate list of values of Sequence/Set/Choice types diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py index e100e75..46f861d 100644 --- a/pyasn1/codec/ber/decoder.py +++ b/pyasn1/codec/ber/decoder.py @@ -403,6 +403,17 @@ class SequenceAndSetDecoderBase(AbstractConstructedDecoder): matchTags=False, matchConstraints=False ) + for holeName, governingName, typesMap in namedTypes.holes: + holeComponent = asn1Object[holeName] + if holeComponent.isValue: + governingComponent = asn1Object[governingName] + if governingComponent in typesMap: + component, rest = decodeFun( + holeComponent.asOctets(), + asn1Spec=typesMap[governingComponent] + ) + asn1Object.setComponentByName(holeName, component, matchTags=False, matchConstraints=False) + if not namedTypes: asn1Object.verifySizeSpec() @@ -1008,7 +1019,7 @@ class Decoder(object): 'codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, value.prettyPrint(), substrate and debug.hexdump(substrate) or '<none>')) if state == stErrorCondition: raise error.PyAsn1Error( - '%s not in asn1Spec: %s' % (tagSet, asn1Spec) + '%s not in asn1Spec: %r' % (tagSet, asn1Spec) ) if debug.logger and debug.logger & debug.flagDecoder: debug.scope.pop() diff --git a/pyasn1/type/namedtype.py b/pyasn1/type/namedtype.py index 3f9ae19..710ce93 100644 --- a/pyasn1/type/namedtype.py +++ b/pyasn1/type/namedtype.py @@ -34,6 +34,8 @@ class NamedType(object): self.__name = name self.__type = asn1Object self.__nameAndType = name, asn1Object + self.__governingName = None + self.__typesMap = None def __repr__(self): return '%s(%r, %r)' % (self.__class__.__name__, self.__name, self.__type) @@ -73,6 +75,19 @@ class NamedType(object): def asn1Object(self): return self.__type + def definedBy(self, governingName, typesMap): + self.__governingName = governingName + self.__typesMap = typesMap + return self + + @property + def governingName(self): + return self.__governingName + + @property + def typesMap(self): + return self.__typesMap + # Backward compatibility def getName(self): @@ -116,6 +131,7 @@ class NamedTypes(object): self.__tagMap = {} self.__hasOptionalOrDefault = None self.__requiredComponents = None + self.__holes = None def __repr__(self): return '%s(%s)' % ( @@ -473,3 +489,15 @@ class NamedTypes(object): [idx for idx, nt in enumerate(self.__namedTypes) if not nt.isOptional and not nt.isDefaulted] ) return self.__requiredComponents + + @property + def holes(self): + if self.__holes is None: + holes = [] + for namedType in self.__namedTypes: + if namedType.governingName: + holes.append((namedType.name, namedType.governingName, namedType.typesMap)) + + self.__holes = holes + + return self.__holes |