diff options
author | Ilya Etingof <etingof@gmail.com> | 2019-06-23 19:48:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-23 19:48:31 +0200 |
commit | 66d329acaaf204eff63ae595fd7d6f56cd530c72 (patch) | |
tree | 46187ae1df17aa9eb728abc2c55ef5ce612c6764 /pyasn1/codec | |
parent | b028644dea4244f1cd2513ab0241c8cb9be43324 (diff) | |
download | pyasn1-66d329acaaf204eff63ae595fd7d6f56cd530c72.tar.gz |
SequenceOf/SetOf to remain a schema objects (#162)
* Add `omitEmptyOptionals` encoder option
Added `omitEmptyOptionals` option which is respected by `Sequence`
and `Set` encoders. When `omitEmptyOptionals` is set to `True`, empty
initialized optional components are not encoded. Default is `False`.
* Change `SequenceOf`/`SetOf` behaviour
- New elements to `SequenceOf`/`SetOf` objects can now be added at any
position - the requirement for the new elements to reside at the end
of the existing ones (i.e. s[len(s)] = 123) is removed.
- Removed default initializer from `SequenceOf`/`SetOf` types to ensure
consistent behaviour with the rest of ASN.1 types. Before this change,
`SequenceOf`/`SetOf` instances immediately become value objects
behaving like an empty list. With this change, `SequenceOf`/`SetOf`
objects remain schema objects unless a component is added or
`.clear()` is called.
- Added `.reset()` method to all constructed types to turn value object
into a schema object.
Diffstat (limited to 'pyasn1/codec')
-rw-r--r-- | pyasn1/codec/ber/decoder.py | 4 | ||||
-rw-r--r-- | pyasn1/codec/ber/encoder.py | 25 |
2 files changed, 24 insertions, 5 deletions
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py index 591bbc4..2e4afbb 100644 --- a/pyasn1/codec/ber/decoder.py +++ b/pyasn1/codec/ber/decoder.py @@ -567,6 +567,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): return asn1Object, tail asn1Object = asn1Spec.clone() + asn1Object.clear() if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId): @@ -682,6 +683,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): else: asn1Object = asn1Spec.clone() + asn1Object.clear() componentType = asn1Spec.componentType @@ -727,6 +729,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): ) asn1Object = asn1Spec.clone() + asn1Object.clear() if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId): @@ -847,6 +850,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): else: asn1Object = asn1Spec.clone() + asn1Object.clear() componentType = asn1Spec.componentType diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py index 65b8514..325ed46 100644 --- a/pyasn1/codec/ber/encoder.py +++ b/pyasn1/codec/ber/encoder.py @@ -4,6 +4,8 @@ # Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com> # License: http://snmplabs.com/pyasn1/license.html # +import sys + from pyasn1 import debug from pyasn1 import error from pyasn1.codec.ber import eoo @@ -93,9 +95,15 @@ class AbstractItemEncoder(object): # base tag? if not idx: - substrate, isConstructed, isOctets = self.encodeValue( - value, asn1Spec, encodeFun, **options - ) + try: + substrate, isConstructed, isOctets = self.encodeValue( + value, asn1Spec, encodeFun, **options + ) + + except error.PyAsn1Error: + exc = sys.exc_info() + raise error.PyAsn1Error( + 'Error encoding %r: %s' % (value, exc[1])) if LOG: LOG('encoded %svalue %s into %s' % ( @@ -518,6 +526,13 @@ class SequenceEncoder(AbstractItemEncoder): substrate = null + omitEmptyOptionals = options.get( + 'omitEmptyOptionals', self.omitEmptyOptionals) + + if LOG: + LOG('%sencoding empty OPTIONAL components' % ( + omitEmptyOptionals and 'not ' or '')) + if asn1Spec is None: # instance of ASN.1 schema value.verifySizeSpec() @@ -538,7 +553,7 @@ class SequenceEncoder(AbstractItemEncoder): LOG('not encoding DEFAULT component %r' % (namedType,)) continue - if self.omitEmptyOptionals: + if omitEmptyOptionals: options.update(ifNotEmpty=namedType.isOptional) chunk = encodeFun(component, asn1Spec, **options) @@ -575,7 +590,7 @@ class SequenceEncoder(AbstractItemEncoder): LOG('not encoding DEFAULT component %r' % (namedType,)) continue - if self.omitEmptyOptionals: + if omitEmptyOptionals: options.update(ifNotEmpty=namedType.isOptional) chunk = encodeFun(component, asn1Spec[idx], **options) |