Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 32 additions & 23 deletions pyftdi/bits.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,10 @@ def tobyte(self, msb: bool = False) -> int:
def tobytes(self, msb: bool = False, msby: bool = False) -> bytearray:
"""Convert the sequence into a sequence of byte values"""
blength = (len(self)+7) & (~0x7)
sequence = list(self._seq)
if not msb:
if msb:
sequence = list(bytes(blength - len(self)) + self._seq)
else:
sequence = list(self._seq + bytes(blength - len(self)))
sequence.reverse()
bytes_ = bytearray()
for pos in range(0, blength, 8):
Expand Down Expand Up @@ -238,26 +240,21 @@ def __ne__(self, other):
return not self == other

def __le__(self, other):
return not self._cmp(other) <= 0
return self._cmp(other) <= 0

def __lt__(self, other):
return not self._cmp(other) < 0
return self._cmp(other) < 0

def __ge__(self, other):
return not self._cmp(other) >= 0
return self._cmp(other) >= 0

def __gt__(self, other):
return not self._cmp(other) > 0
return self._cmp(other) > 0

def _cmp(self, other):
# the bit sequence should be of the same length
ld = len(self) - len(other)
if ld:
return ld
for n, (x, y) in enumerate(zip(self._seq, other.sequence()), start=1):
if xor(x, y):
return n
return 0
a = int(self)
b = int(other)
return (a > b) - (a < b)

def __repr__(self):
# cannot use bin() as it truncates the MSB zero bits
Expand Down Expand Up @@ -418,15 +415,27 @@ def __int__(self):
"an integral type")
return BitSequence.__int__(self)

def __cmp__(self, other):
# the bit sequence should be of the same length
ld = len(self) - len(other)
if ld:
return ld
for n, (x, y) in enumerate(zip(self._seq, other.sequence()), start=1):
if x is not y:
return n
return 0
def _pseudo_int(self):
# returns int value of sequence by treating it as ternary sequence
value = 0
bit_value = {
0: 0,
BitZSequence.Z: 1,
1: 2,
}
for b in reversed(self._seq):
value *= 3
value += bit_value[b]
return value

def _cmp(self, other):
try:
a = self._pseudo_int()
b = other._pseudo_int()
except AttributeError: # if other is not BitZSequence, compare both as normal BitSequence
a = int(self)
b = int(other)
return (a > b) - (a < b)

def __and__(self, other):
if not isinstance(self, BitSequence):
Expand Down
31 changes: 21 additions & 10 deletions pyftdi/tests/bits.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ def test_bitwise_ops(self):
self.assertEqual(repr(self.bzs4.invert()), '00Z0Z101ZZ1011')
self.assertLess(self.bs5, self.bs6)
self.assertLessEqual(self.bs5, self.bs6)
self.assertLess(self.bs6, self.bs5)
self.assertLessEqual(self.bs6, self.bs5)
self.assertGreater(self.bs6, self.bs5)
self.assertGreaterEqual(self.bs6, self.bs5)

def test_cmp(self):
self.assertTrue(self.bs1 == self.bs1)
Expand All @@ -66,12 +66,12 @@ def test_cmp(self):
self.assertTrue(self.bzs1 != self.bzs2)
self.assertTrue(self.bs1 == self.bzs1)
self.assertTrue(self.bzs1 == self.bs1)
self.assertTrue(self.bzs3 != self.bzs2)
self.assertTrue(self.bzs3 == self.bzs2)
self.assertNotEqual(self.bzs4, self.bzs5)
bzs = BitZSequence(self.bs7)
self.assertTrue(bzs == self.bs7)
bzs |= BitZSequence('00Z0Z000ZZ0Z00')
self.assertFalse(bzs == self.bs7)
self.assertFalse(bzs == BitZSequence(self.bs7))
self.assertTrue(bzs.matches(self.bs7))

def test_representation(self):
Expand Down Expand Up @@ -161,9 +161,9 @@ def test_misc(self):
bl = [ba, bb]
bl.sort(key=int)
self.assertEqual(str(bl), "[00110000000000, 0011000000000000]")
self.assertEqual(str(ba.tobytes()), "[48, 0]")
self.assertEqual(str(ba.tobytes(True)), "[0, 12]")
self.assertEqual(str(bb.tobytes(True)), "[0, 12]")
self.assertEqual(ba.tobytes(), bytearray([48, 0]))
self.assertEqual(ba.tobytes(True), bytearray([0, 12]))
self.assertEqual(bb.tobytes(True), bytearray([0, 12]))

b = BitSequence(length=254)
b[0:4] = '1111'
Expand All @@ -174,9 +174,9 @@ def test_misc(self):
'00000000 00000000 00000000 00000000 00000000 00000000 00000000 '
'00000000 00000000 00000000 00000000 00000000 00000000 00001111')
self.assertEqual(
str(b.tobytes()),
'[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '
'0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15]')
b.tobytes(),
bytearray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15]))

b = BitSequence(bytes_=[0xa0, '\x0f', 0x77], msb=False, msby=False)
self.assertEqual(str(['%02x' % x for x in b.tobytes(False)]),
Expand All @@ -203,6 +203,17 @@ def test_concat(self):
'1111101010100111Z1Z010ZZ0100')
self.assertEqual(repr(self.bs7+self.bzs4),
'11Z1Z010ZZ010011111010101001')

def test_int(self):
self.assertEqual(int(BitSequence(65535)), 65535)
self.assertEqual(int(BitSequence(65536)), 65536)
self.assertEqual(int(BitSequence(65537)), 65537)
self.assertEqual(int(BitSequence(65539)), 65539)
self.assertEqual(int.from_bytes(BitSequence(65535).tobytes(), byteorder='big'), 65535)
self.assertEqual(int.from_bytes(BitSequence(65536).tobytes(), byteorder='big'), 65536)
self.assertEqual(int.from_bytes(BitSequence(65537).tobytes(), byteorder='big'), 65537)
self.assertEqual(int.from_bytes(BitSequence(65539).tobytes(), byteorder='big'), 65539)
self.assertEqual(int.from_bytes(BitSequence(65539).tobytes(msby=True), byteorder='little'), 65539)


def suite():
Expand Down