From: Joseph Spiros Date: Wed, 13 Apr 2011 04:40:10 +0000 (-0400) Subject: Fixed and cleaned up signed integer reading and encoding. Implemented some value... X-Git-Url: http://git.ithinksw.org/~jspiros/python-ebml.git/commitdiff_plain/d8f926028d6d4368348ad27fb2c7beef29eda9c0 Fixed and cleaned up signed integer reading and encoding. Implemented some value tests. --- diff --git a/ebml/core.py b/ebml/core.py index 24d849f..e076c8b 100644 --- a/ebml/core.py +++ b/ebml/core.py @@ -138,13 +138,13 @@ def read_signed_integer(stream, size): value = 0 if size > 0: - byte = ord(stream.read(1)) - if (byte & 0b10000000) == 0b10000000: - value = -1 << 8 - value |= byte + first_byte = ord(stream.read(1)) + value = first_byte for i in xrange(1, size): byte = ord(stream.read(1)) - value = (value << 1) | byte + value = (value << 8) | byte + if (first_byte & 0b10000000) == 0b10000000: + value = -(2**(size*8) - value) return value @@ -391,9 +391,7 @@ def encode_signed_integer(sint, length=None): if sint >= 0: uint = sint else: - uint = 0b10000000 << (length - 1) - uint += sint - uint |= 0b10000000 << (length - 1) + uint = 2**(length*8) - abs(sint) data = bytearray(length) for index in reversed(xrange(length)): diff --git a/ebml/tests/test_core.py b/ebml/tests/test_core.py index 54a46a7..ce72b69 100644 --- a/ebml/tests/test_core.py +++ b/ebml/tests/test_core.py @@ -59,5 +59,48 @@ class ElementIDTests(unittest.TestCase): self.assert_roundtrip(id_) +class ValueTestCase(unittest.TestCase): + encoder = None + reader = None + + def assert_roundtrip(self, value): + if self.encoder is not None and self.reader is not None: + encoded = self.encoder(value) + encoded_stream = StringIO(encoded) + self.assertEqual(value, self.reader(encoded_stream, len(encoded))) + else: + raise NotImplementedError + + +class UnsignedIntegerTests(ValueTestCase): + encoder = staticmethod(encode_unsigned_integer) + reader = staticmethod(read_unsigned_integer) + maximum = 2**64 - 1 + + def test_random(self): + for value in (randint(0, self.maximum) for i in xrange(0, 10000)): + self.assert_roundtrip(value) + + def test_maximum(self): + self.assert_roundtrip(self.maximum) + + +class SignedIntegerTests(ValueTestCase): + encoder = staticmethod(encode_signed_integer) + reader = staticmethod(read_signed_integer) + minimum = -(2**63) + maximum = (2**63) - 1 + + def test_random(self): + for value in (randint(self.minimum, self.maximum) for i in xrange(0, 10000)): + self.assert_roundtrip(value) + + def test_minimum(self): + self.assert_roundtrip(self.minimum) + + def test_maximum(self): + self.assert_roundtrip(self.maximum) + + if __name__ == '__main__': unittest.main() \ No newline at end of file