aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Etingof <ietingof@redhat.com>2017-03-31 11:48:32 +0200
committerIlya Etingof <ietingof@redhat.com>2017-03-31 11:48:32 +0200
commit36fe017a3abb7c741c51cada06ccfca4a30a786f (patch)
treec2c5e259d04009d5eb52141d42a29a56806c6f37
parent2d7f05df7c68cce0bea6db3c68a46d2463b2eab4 (diff)
downloadpyasn1-36fe017a3abb7c741c51cada06ccfca4a30a786f.tar.gz
EndOfOctets refactored into singleton
-rw-r--r--CHANGES.rst2
-rw-r--r--pyasn1/codec/ber/decoder.py20
-rw-r--r--pyasn1/codec/ber/eoo.py8
-rw-r--r--tests/codec/ber/test_decoder.py2
4 files changed, 21 insertions, 11 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 6aab1cf..5db6c6f 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -20,6 +20,8 @@ Revision 0.2.4, released XX-03-2017
reordered components handling when not necessary.
- Tags and constraints-related getter methods refactored into descriptors/properties.
- The .hasValue() method refactored into .isValue property
+- The end-of-octets type refactored to ensure it is a singleton. Codecs
+ changed to rely on that for better performance.
- Codecs lookup made more efficient at BER/CER/DER decoder main loop by
assigning `typeId` to every ASN.1 type, not just ambiguous ones.
- The .getComponent*() methods of constructed ASN.1 types changed
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index 13ed59c..b688804 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -76,7 +76,7 @@ class ExplicitTagDecoder(AbstractSimpleDecoder):
)
value, substrate = decodeFun(substrate, asn1Spec, tagSet, length)
terminator, substrate = decodeFun(substrate, allowEoo=True)
- if eoo.endOfOctets.isSameTypeWith(terminator) and terminator == eoo.endOfOctets:
+ if terminator is eoo.endOfOctets:
return value, substrate
else:
raise error.PyAsn1Error('Missing end-of-octets terminator')
@@ -150,7 +150,7 @@ class BitStringDecoder(AbstractSimpleDecoder):
while substrate:
component, substrate = decodeFun(substrate, self.protoComponent, allowEoo=True)
- if eoo.endOfOctets.isSameTypeWith(component) and component == eoo.endOfOctets:
+ if component is eoo.endOfOctets:
break
bitString += component
@@ -189,7 +189,7 @@ class OctetStringDecoder(AbstractSimpleDecoder):
while substrate:
component, substrate = decodeFun(substrate, self.protoComponent,
allowEoo=True)
- if eoo.endOfOctets.isSameTypeWith(component) and component == eoo.endOfOctets:
+ if component is eoo.endOfOctets:
break
asn1Object += component
else:
@@ -399,7 +399,7 @@ class SequenceAndSetDecoderBase(AbstractConstructedDecoder):
while substrate:
asn1Spec = self._getComponentTagMap(asn1Object, idx)
component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True)
- if eoo.endOfOctets.isSameTypeWith(component) and component == eoo.endOfOctets:
+ if component is eoo.endOfOctets:
break
idx = self._getComponentPositionByType(
asn1Object, component.effectiveTagSet, idx
@@ -431,7 +431,7 @@ class SequenceAndSetDecoderBase(AbstractConstructedDecoder):
)
component, substrate = decodeFun(substrate, eoo.endOfOctets, allowEoo=True)
- if not eoo.endOfOctets.isSameTypeWith(component) or component != eoo.endOfOctets:
+ if component is not eoo.endOfOctets:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
)
@@ -486,7 +486,7 @@ class SequenceOfDecoder(AbstractConstructedDecoder):
idx = 0
while substrate:
component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True)
- if eoo.endOfOctets.isSameTypeWith(component) and component == eoo.endOfOctets:
+ if component is eoo.endOfOctets:
break
asn1Object.setComponentByPosition(
idx, component,
@@ -557,7 +557,7 @@ class ChoiceDecoder(AbstractConstructedDecoder):
component, substrate = decodeFun(substrate, asn1Object.componentTagMap)
# eat up EOO marker
eooMarker, substrate = decodeFun(substrate, allowEoo=True)
- if not eoo.endOfOctets.isSameTypeWith(eooMarker) or eooMarker != eoo.endOfOctets:
+ if eooMarker is not eoo.endOfOctets:
raise error.PyAsn1Error('No EOO seen before substrate ends')
else:
component, substrate = decodeFun(
@@ -581,7 +581,7 @@ class AnyDecoder(AbstractSimpleDecoder):
length, state, decodeFun, substrateFun):
if asn1Spec is None or asn1Spec is not None and tagSet != asn1Spec.tagSet:
# untagged Any container, recover inner header substrate
- length = length + len(fullSubstrate) - len(substrate)
+ length += len(fullSubstrate) - len(substrate)
substrate = fullSubstrate
if substrateFun:
return substrateFun(self._createComponent(asn1Spec, tagSet),
@@ -607,9 +607,9 @@ class AnyDecoder(AbstractSimpleDecoder):
return substrateFun(asn1Object, substrate, length)
while substrate:
component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True)
- if eoo.endOfOctets.isSameTypeWith(component) and component == eoo.endOfOctets:
+ if component is eoo.endOfOctets:
break
- asn1Object = asn1Object + component
+ asn1Object += component
else:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
diff --git a/pyasn1/codec/ber/eoo.py b/pyasn1/codec/ber/eoo.py
index 7a601ee..595fca2 100644
--- a/pyasn1/codec/ber/eoo.py
+++ b/pyasn1/codec/ber/eoo.py
@@ -13,5 +13,13 @@ class EndOfOctets(base.AbstractSimpleAsn1Item):
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x00)
)
+ _instance = None
+
+ def __new__(cls):
+ if cls._instance is None:
+ cls._instance = object.__new__(cls)
+
+ return cls._instance
+
endOfOctets = EndOfOctets()
diff --git a/tests/codec/ber/test_decoder.py b/tests/codec/ber/test_decoder.py
index f3b6c7d..18d7f08 100644
--- a/tests/codec/ber/test_decoder.py
+++ b/tests/codec/ber/test_decoder.py
@@ -768,7 +768,7 @@ class EndOfOctetsTestCase(unittest.TestCase):
def testExpectedEoo(self):
result, remainder = decoder.decode(ints2octs((0, 0)), allowEoo=True)
- assert eoo.endOfOctets.isSameTypeWith(result) and result == eoo.endOfOctets
+ assert eoo.endOfOctets.isSameTypeWith(result) and result == eoo.endOfOctets and result is eoo.endOfOctets
assert remainder == null
def testDefiniteNoEoo(self):