summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelie <elie>2014-10-26 08:45:26 +0000
committerelie <elie>2014-10-26 08:45:26 +0000
commite2469877057a0f5a6171a532ce3e6207ef27395e (patch)
tree93fb0b5198c7e36fdfd1622636bb0be22efc36e7
parent615c62d9b674bb78888028169a64278dac8e58f5 (diff)
downloadpyasn1-e2469877057a0f5a6171a532ce3e6207ef27395e.tar.gz
BitString encoder/decoder performance improved
-rw-r--r--CHANGES1
-rw-r--r--pyasn1/codec/ber/decoder.py4
-rw-r--r--pyasn1/codec/ber/encoder.py18
3 files changed, 14 insertions, 9 deletions
diff --git a/CHANGES b/CHANGES
index 3f96608..4e17c10 100644
--- a/CHANGES
+++ b/CHANGES
@@ -41,6 +41,7 @@ Revision 0.1.8
- The Integer.__invert__ Python magic method implemented.
- The OctetString.__int__() and .__float__() magic methods implemented.
- Handle the case of null writer at Debug printer.
+- BitString encoder/decoder performance improved.
- Fix to NamedType.__repr__() to work properly.
- Fixes to __repr__() implementation of many built-in ASN.1 types to take into
account all of their initializers such as tagSet, subtypeSpec etc.
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index 505d00f..28a666d 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -129,14 +129,14 @@ class BitStringDecoder(AbstractSimpleDecoder):
'Trailing bits overflow %s' % trailingBits
)
head = head[1:]
- lsb = p = 0; l = len(head)-1; b = ()
+ lsb = p = 0; l = len(head)-1; b = []
while p <= l:
if p == l:
lsb = trailingBits
j = 7
o = oct2int(head[p])
while j >= lsb:
- b = b + ((o>>j)&0x01,)
+ b.append((o>>j)&0x01)
j = j - 1
p = p + 1
return self._createComponent(asn1Spec, tagSet, b), tail
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index ff215ac..7f204c8 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -114,13 +114,17 @@ class IntegerEncoder(AbstractItemEncoder):
class BitStringEncoder(AbstractItemEncoder):
def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
if not maxChunkSize or len(value) <= maxChunkSize*8:
- r = {}; l = len(value); p = 0; j = 7
- while p < l:
- i, j = divmod(p, 8)
- r[i] = r.get(i,0) | value[p]<<(7-j)
- p = p + 1
- keys = list(r); keys.sort()
- return int2oct(7-j) + ints2octs([r[k] for k in keys]), 0
+ out_len = (len(value) + 7) // 8
+ out_list = out_len * [0]
+ j = 7
+ i = -1
+ for val in value:
+ j += 1
+ if j == 8:
+ i += 1
+ j = 0
+ out_list[i] = out_list[i] | val << (7-j)
+ return int2oct(7-j) + ints2octs(out_list), 0
else:
pos = 0; substrate = null
while 1: