#!/usr/bin/env python import unittest import sys sys.path.insert(0, '..') import bitstring import copy import os import collections from bitstring import BitStream, ConstBitStream, pack from bitstring import ByteStore, offsetcopy class FlexibleInitialisation(unittest.TestCase): def testFlexibleInitialisation(self): a = BitStream('uint:8=12') c = BitStream(' uint : 8 = 12') self.assertTrue(a == c == BitStream(uint=12, length=8)) self.assertEqual(a.uint, 12) a = BitStream(' int:2= -1') b = BitStream('int :2 = -1') c = BitStream(' int: 2 =-1 ') self.assertTrue(a == b == c == BitStream(int=-1, length=2)) def testFlexibleInitialisation2(self): h = BitStream('hex=12') o = BitStream('oct=33') b = BitStream('bin=10') self.assertEqual(h, '0x12') self.assertEqual(o, '0o33') self.assertEqual(b, '0b10') def testFlexibleInitialisation3(self): for s in ['se=-1', ' se = -1 ', 'se = -1']: a = BitStream(s) self.assertEqual(a.se, -1) for s in ['ue=23', 'ue =23', 'ue = 23']: a = BitStream(s) self.assertEqual(a.ue, 23) def testMultipleStringInitialisation(self): a = BitStream('0b1 , 0x1') self.assertEqual(a, '0b10001') a = BitStream('ue=5, ue=1, se=-2') self.assertEqual(a.read('ue'), 5) self.assertEqual(a.read('ue'), 1) self.assertEqual(a.read('se'), -2) b = BitStream('uint:32 = 12, 0b11') + 'int:100=-100, 0o44' self.assertEqual(b.read(32).uint, 12) self.assertEqual(b.read(2).bin, '11') self.assertEqual(b.read(100).int, -100) class Reading(unittest.TestCase): def testReadBits(self): s = BitStream(bytes=b'\x4d\x55') self.assertEqual(s.read(4).hex, '4') self.assertEqual(s.read(8).hex, 'd5') self.assertEqual(s.read(1), [0]) self.assertEqual(s.read(3).bin, '101') self.assertFalse(s.read(0)) def testReadByte(self): s = BitStream(hex='4d55') self.assertEqual(s.read(8).hex, '4d') self.assertEqual(s.read(8).hex, '55') def testReadBytes(self): s = BitStream(hex='0x112233448811') self.assertEqual(s.read(3 * 8).hex, '112233') self.assertRaises(ValueError, s.read, -2 * 8) s.bitpos += 1 self.assertEqual(s.read(2 * 8).bin, '1000100100010000') def testReadUE(self): self.assertRaises(bitstring.InterpretError, BitStream('')._getue) # The numbers 0 to 8 as unsigned Exponential-Golomb codes s = BitStream(bin='1 010 011 00100 00101 00110 00111 0001000 0001001') self.assertEqual(s.pos, 0) for i in range(9): self.assertEqual(s.read('ue'), i) self.assertRaises(bitstring.ReadError, s.read, 'ue') def testReadSE(self): s = BitStream(bin='010 00110 0001010 0001000 00111') self.assertEqual(s.read('se'), 1) self.assertEqual(s.read('se'), 3) self.assertEqual(s.readlist(3 * ['se']), [5, 4, -3]) class Find(unittest.TestCase): def testFind1(self): s = ConstBitStream(bin='0b0000110110000') self.assertTrue(s.find(BitStream(bin='11011'), False)) self.assertEqual(s.bitpos, 4) self.assertEqual(s.read(5).bin, '11011') s.bitpos = 0 self.assertFalse(s.find('0b11001', False)) def testFind2(self): s = BitStream(bin='0') self.assertTrue(s.find(s, False)) self.assertEqual(s.pos, 0) self.assertFalse(s.find('0b00', False)) self.assertRaises(ValueError, s.find, BitStream(), False) def testFindWithOffset(self): s = BitStream(hex='0x112233')[4:] self.assertTrue(s.find('0x23', False)) self.assertEqual(s.pos, 8) def testFindCornerCases(self): s = BitStream(bin='000111000111') self.assertTrue(s.find('0b000')) self.assertEqual(s.pos, 0) self.assertTrue(s.find('0b000')) self.assertEqual(s.pos, 0) self.assertTrue(s.find('0b0111000111')) self.assertEqual(s.pos, 2) self.assertTrue(s.find('0b000', start=2)) self.assertEqual(s.pos, 6) self.assertTrue(s.find('0b111', start=6)) self.assertEqual(s.pos, 9) s.pos += 2 self.assertTrue(s.find('0b1', start=s.pos)) def testFindBytes(self): s = BitStream('0x010203040102ff') self.assertFalse(s.find('0x05', bytealigned=True)) self.assertTrue(s.find('0x02', bytealigned=True)) self.assertEqual(s.read(16).hex, '0203') self.assertTrue(s.find('0x02', start=s.bitpos, bytealigned=True)) s.read(1) self.assertFalse(s.find('0x02', start=s.bitpos, bytealigned=True)) def testFindBytesAlignedCornerCases(self): s = BitStream('0xff') self.assertTrue(s.find(s)) self.assertFalse(s.find(BitStream(hex='0x12'))) self.assertFalse(s.find(BitStream(hex='0xffff'))) def testFindBytesBitpos(self): s = BitStream(hex='0x1122334455') s.pos = 2 s.find('0x66', bytealigned=True) self.assertEqual(s.pos, 2) s.pos = 38 s.find('0x66', bytealigned=True) self.assertEqual(s.pos, 38) def testFindByteAligned(self): s = BitStream(hex='0x12345678') self.assertTrue(s.find(BitStream(hex='0x56'), bytealigned=True)) self.assertEqual(s.bytepos, 2) s.pos = 0 self.assertFalse(s.find(BitStream(hex='0x45'), bytealigned=True)) s = BitStream('0x1234') s.find('0x1234') self.assertTrue(s.find('0x1234')) s += '0b111' s.pos = 3 s.find('0b1', start=17, bytealigned=True) self.assertFalse(s.find('0b1', start=17, bytealigned=True)) self.assertEqual(s.pos, 3) def testFindByteAlignedWithOffset(self): s = BitStream(hex='0x112233')[4:] self.assertTrue(s.find(BitStream(hex='0x23'))) def testFindByteAlignedErrors(self): s = BitStream(hex='0xffff') self.assertRaises(ValueError, s.find, '') self.assertRaises(ValueError, s.find, BitStream()) class Rfind(unittest.TestCase): def testRfind(self): a = BitStream('0b001001001') b = a.rfind('0b001') self.assertEqual(b, (6,)) self.assertEqual(a.pos, 6) big = BitStream(length=100000) + '0x12' + BitStream(length=10000) found = big.rfind('0x12', bytealigned=True) self.assertEqual(found, (100000,)) self.assertEqual(big.pos, 100000) def testRfindByteAligned(self): a = BitStream('0x8888') b = a.rfind('0b1', bytealigned=True) self.assertEqual(b, (8,)) self.assertEqual(a.pos, 8) def testRfindStartbit(self): a = BitStream('0x0000ffffff') b = a.rfind('0x0000', start=1, bytealigned=True) self.assertEqual(b, ()) self.assertEqual(a.pos, 0) b = a.rfind('0x00', start=1, bytealigned=True) self.assertEqual(b, (8,)) self.assertEqual(a.pos, 8) def testRfindEndbit(self): a = BitStream('0x000fff') b = a.rfind('0b011', bytealigned=False, start=0, end=14) self.assertEqual(bool(b), True) b = a.rfind('0b011', False, 0, 13) self.assertEqual(b, ()) def testRfindErrors(self): a = BitStream('0x43234234') self.assertRaises(ValueError, a.rfind, '', bytealigned=True) self.assertRaises(ValueError, a.rfind, '0b1', start=-99, bytealigned=True) self.assertRaises(ValueError, a.rfind, '0b1', end=33, bytealigned=True) self.assertRaises(ValueError, a.rfind, '0b1', start=10, end=9, bytealigned=True) class Shift(unittest.TestCase): def testShiftLeft(self): s = BitStream('0b1010') t = s << 1 self.assertEqual(s.bin, '1010') self.assertEqual(t.bin, '0100') t = t << 0 self.assertEqual(t, '0b0100') t = t << 100 self.assertEqual(t.bin, '0000') def testShiftLeftErrors(self): s = BitStream() self.assertRaises(ValueError, s.__lshift__, 1) s = BitStream('0xf') self.assertRaises(ValueError, s.__lshift__, -1) def testShiftRight(self): s = BitStream('0b1010') t = s >> 1 self.assertEqual(s.bin, '1010') self.assertEqual(t.bin, '0101') q = s >> 0 self.assertEqual(q, '0b1010') q.replace('0b1010', '') s = s >> 100 self.assertEqual(s.bin, '0000') def testShiftRightErrors(self): s = BitStream() self.assertRaises(ValueError, s.__rshift__, 1) s = BitStream('0xf') self.assertRaises(ValueError, s.__rshift__, -1) def testShiftRightInPlace(self): s = BitStream('0xffff')[4:12] s >>= 1 self.assertEqual(s, '0b01111111') s = BitStream('0b11011') s >>= 2 self.assertEqual(s.bin, '00110') s >>= 100000000000000 self.assertEqual(s.bin, '00000') s = BitStream('0xff') s >>= 1 self.assertEqual(s, '0x7f') s >>= 0 self.assertEqual(s, '0x7f') def testShiftRightInPlaceErrors(self): s = BitStream() self.assertRaises(ValueError, s.__irshift__, 1) s += '0b11' self.assertRaises(ValueError, s.__irshift__, -1) def testShiftLeftInPlace(self): s = BitStream('0xffff') t = s[4:12] t <<= 2 self.assertEqual(t, '0b11111100') s = BitStream('0b11011') s <<= 2 self.assertEqual(s.bin, '01100') s <<= 100000000000000000000 self.assertEqual(s.bin, '00000') s = BitStream('0xff') s <<= 1 self.assertEqual(s, '0xfe') s <<= 0 self.assertEqual(s, '0xfe') def testShiftLeftInPlaceErrors(self): s = BitStream() self.assertRaises(ValueError, s.__ilshift__, 1) s += '0b11' self.assertRaises(ValueError, s.__ilshift__, -1) class Replace(unittest.TestCase): def testReplace1(self): a = BitStream('0b1') n = a.replace('0b1', '0b0', bytealigned=True) self.assertEqual(a.bin, '0') self.assertEqual(n, 1) n = a.replace('0b1', '0b0', bytealigned=True) self.assertEqual(n, 0) def testReplace2(self): a = BitStream('0b00001111111') n = a.replace('0b1', '0b0', bytealigned=True) self.assertEqual(a.bin, '00001111011') self.assertEqual(n, 1) n = a.replace('0b1', '0b0', bytealigned=False) self.assertEqual(a.bin, '00000000000') self.assertEqual(n, 6) def testReplace3(self): a = BitStream('0b0') n = a.replace('0b0', '0b110011111', bytealigned=True) self.assertEqual(n, 1) self.assertEqual(a.bin, '110011111') n = a.replace('0b11', '', bytealigned=False) self.assertEqual(n, 3) self.assertEqual(a.bin, '001') def testReplace4(self): a = BitStream('0x00114723ef4732344700') n = a.replace('0x47', '0x00', bytealigned=True) self.assertEqual(n, 3) self.assertEqual(a.hex, '00110023ef0032340000') a.replace('0x00', '', bytealigned=True) self.assertEqual(a.hex, '1123ef3234') a.replace('0x11', '', start=1, bytealigned=True) self.assertEqual(a.hex, '1123ef3234') a.replace('0x11', '0xfff', end=7, bytealigned=True) self.assertEqual(a.hex, '1123ef3234') a.replace('0x11', '0xfff', end=8, bytealigned=True) self.assertEqual(a.hex, 'fff23ef3234') def testReplace5(self): a = BitStream('0xab') b = BitStream('0xcd') c = BitStream('0xabef') c.replace(a, b) self.assertEqual(c, '0xcdef') self.assertEqual(a, '0xab') self.assertEqual(b, '0xcd') a = BitStream('0x0011223344') a.pos = 12 a.replace('0x11', '0xfff', bytealigned=True) self.assertEqual(a.pos, 8) self.assertEqual(a, '0x00fff223344') def testReplaceWithSelf(self): a = BitStream('0b11') a.replace('0b1', a) self.assertEqual(a, '0xf') a.replace(a, a) self.assertEqual(a, '0xf') def testReplaceCount(self): a = BitStream('0x223344223344223344') n = a.replace('0x2', '0x0', count=0, bytealigned=True) self.assertEqual(n, 0) self.assertEqual(a.hex, '223344223344223344') n = a.replace('0x2', '0x0', count=1, bytealigned=True) self.assertEqual(n, 1) self.assertEqual(a.hex, '023344223344223344') n = a.replace('0x33', '', count=2, bytealigned=True) self.assertEqual(n, 2) self.assertEqual(a.hex, '02442244223344') n = a.replace('0x44', '0x4444', count=1435, bytealigned=True) self.assertEqual(n, 3) self.assertEqual(a.hex, '02444422444422334444') def testReplaceBitpos(self): a = BitStream('0xff') a.bitpos = 8 a.replace('0xff', '', bytealigned=True) self.assertEqual(a.bitpos, 0) a = BitStream('0b0011110001') a.bitpos = 4 a.replace('0b1', '0b000') self.assertEqual(a.bitpos, 8) a = BitStream('0b1') a.bitpos = 1 a.replace('0b1', '0b11111', bytealigned=True) self.assertEqual(a.bitpos, 5) a.replace('0b11', '0b0', False) self.assertEqual(a.bitpos, 3) a.append('0b00') a.replace('0b00', '0xffff') self.assertEqual(a.bitpos, 17) def testReplaceErrors(self): a = BitStream('0o123415') self.assertRaises(ValueError, a.replace, '', '0o7', bytealigned=True) self.assertRaises(ValueError, a.replace, '0b1', '0b1', start=-100, bytealigned=True) self.assertRaises(ValueError, a.replace, '0b1', '0b1', end=19, bytealigned=True) class SliceAssignment(unittest.TestCase): # TODO: Move this to another class def testSetSlice(self): a = BitStream() a[0:0] = '0xabcdef' self.assertEqual(a.bytepos, 3) a[4:16] = '' self.assertEqual(a, '0xaef') self.assertEqual(a.bitpos, 4) a[8:] = '0x00' self.assertEqual(a, '0xae00') self.assertEqual(a.bytepos, 2) a += '0xf' a[8:] = '0xe' self.assertEqual(a, '0xaee') self.assertEqual(a.bitpos, 12) b = BitStream() b[0:800] = '0xffee' self.assertEqual(b, '0xffee') b[4:48] = '0xeed123' self.assertEqual(b, '0xfeed123') b[-800:8] = '0x0000' self.assertEqual(b, '0x0000ed123') a = BitStream('0xabcde') self.assertEqual(a[-100:-90], '') self.assertEqual(a[-100:-16], '0xa') a[-100:-16] = '0x0' self.assertEqual(a, '0x0bcde') def testInsertingUsingSetItem(self): a = BitStream() a[0:0] = '0xdeadbeef' self.assertEqual(a, '0xdeadbeef') self.assertEqual(a.bytepos, 4) a[16:16] = '0xfeed' self.assertEqual(a, '0xdeadfeedbeef') self.assertEqual(a.bytepos, 4) a[0:0] = '0xa' self.assertEqual(a, '0xadeadfeedbeef') self.assertEqual(a.bitpos, 4) a.bytepos = 6 a[0:0] = '0xff' self.assertEqual(a.bytepos, 1) a[8:0] = '0x00000' self.assertTrue(a.startswith('0xff00000adead')) def testSliceAssignmentBitPos(self): a = BitStream('int:64=-1') a.pos = 64 a[0:8] = '' self.assertEqual(a.pos, 0) a.pos = 52 a[48:56] = '0x0000' self.assertEqual(a.pos, 64) a[10:10] = '0x0' self.assertEqual(a.pos, 14) a[56:68] = '0x000' self.assertEqual(a.pos, 14) class Pack(unittest.TestCase): def testPack1(self): s = bitstring.pack('uint:6, bin, hex, int:6, se, ue, oct', 10, '0b110', 'ff', -1, -6, 6, '54') t = BitStream('uint:6=10, 0b110, 0xff, int:6=-1, se=-6, ue=6, oct=54') self.assertEqual(s, t) self.assertRaises(bitstring.CreationError, pack, 'tomato', '0') self.assertRaises(bitstring.CreationError, pack, 'uint', 12) self.assertRaises(bitstring.CreationError, pack, 'hex', 'penguin') self.assertRaises(bitstring.CreationError, pack, 'hex12', '0x12') def testPackWithLiterals(self): s = bitstring.pack('0xf') self.assertEqual(s, '0xf') self.assertTrue(type(s), BitStream) s = pack('0b1') self.assertEqual(s, '0b1') s = pack('0o7') self.assertEqual(s, '0o7') s = pack('int:10=-1') self.assertEqual(s, '0b1111111111') s = pack('uint:10=1') self.assertEqual(s, '0b0000000001') s = pack('ue=12') self.assertEqual(s.ue, 12) s = pack('se=-12') self.assertEqual(s.se, -12) s = pack('bin=01') self.assertEqual(s.bin, '01') s = pack('hex=01') self.assertEqual(s.hex, '01') s = pack('oct=01') self.assertEqual(s.oct, '01') def testPackWithDict(self): a = pack('uint:6=width, se=height', height=100, width=12) w, h = a.unpack('uint:6, se') self.assertEqual(w, 12) self.assertEqual(h, 100) d = {} d['w'] = '0xf' d['300'] = 423 d['e'] = '0b1101' a = pack('int:100=300, bin=e, uint:12=300', **d) x, y, z = a.unpack('int:100, bin, uint:12') self.assertEqual(x, 423) self.assertEqual(y, '1101') self.assertEqual(z, 423) def testPackWithDict2(self): a = pack('int:5, bin:3=b, 0x3, bin=c, se=12', 10, b='0b111', c='0b1') b = BitStream('int:5=10, 0b111, 0x3, 0b1, se=12') self.assertEqual(a, b) a = pack('bits:3=b', b=BitStream('0b101')) self.assertEqual(a, '0b101') a = pack('bits:24=b', b=BitStream('0x001122')) self.assertEqual(a, '0x001122') def testPackWithDict3(self): s = pack('hex:4=e, hex:4=0xe, hex:4=e', e='f') self.assertEqual(s, '0xfef') s = pack('sep', sep='0b00') self.assertEqual(s, '0b00') def testPackWithDict4(self): s = pack('hello', hello='0xf') self.assertEqual(s, '0xf') s = pack('x, y, x, y, x', x='0b10', y='uint:12=100') t = BitStream('0b10, uint:12=100, 0b10, uint:12=100, 0b10') self.assertEqual(s, t) a = [1, 2, 3, 4, 5] s = pack('int:8, div,' * 5, *a, **{'div': '0b1'}) t = BitStream('int:8=1, 0b1, int:8=2, 0b1, int:8=3, 0b1, int:8=4, 0b1, int:8=5, 0b1') self.assertEqual(s, t) def testPackWithLocals(self): width = 352 height = 288 s = pack('uint:12=width, uint:12=height', **locals()) self.assertEqual(s, '0x160120') def testPackWithLengthRestriction(self): s = pack('bin:3', '0b000') self.assertRaises(bitstring.CreationError, pack, 'bin:3', '0b0011') self.assertRaises(bitstring.CreationError, pack, 'bin:3', '0b11') self.assertRaises(bitstring.CreationError, pack, 'bin:3=0b0011') self.assertRaises(bitstring.CreationError, pack, 'bin:3=0b11') s = pack('hex:4', '0xf') self.assertRaises(bitstring.CreationError, pack, 'hex:4', '0b111') self.assertRaises(bitstring.CreationError, pack, 'hex:4', '0b11111') self.assertRaises(bitstring.CreationError, pack, 'hex:8=0xf') s = pack('oct:6', '0o77') self.assertRaises(bitstring.CreationError, pack, 'oct:6', '0o1') self.assertRaises(bitstring.CreationError, pack, 'oct:6', '0o111') self.assertRaises(bitstring.CreationError, pack, 'oct:3', '0b1') self.assertRaises(bitstring.CreationError, pack, 'oct:3=hello', hello='0o12') s = pack('bits:3', BitStream('0b111')) self.assertRaises(bitstring.CreationError, pack, 'bits:3', BitStream('0b11')) self.assertRaises(bitstring.CreationError, pack, 'bits:3', BitStream('0b1111')) self.assertRaises(bitstring.CreationError, pack, 'bits:12=b', b=BitStream('0b11')) def testPackNull(self): s = pack('') self.assertFalse(s) s = pack(',') self.assertFalse(s) s = pack(',,,,,0b1,,,,,,,,,,,,,0b1,,,,,,,,,,') self.assertEqual(s, '0b11') s = pack(',,uint:12,,bin:3,', 100, '100') a, b = s.unpack(',,,uint:12,,,,bin:3,,,') self.assertEqual(a, 100) self.assertEqual(b, '100') def testPackDefaultUint(self): s = pack('10, 5', 1, 2) a, b = s.unpack('10, 5') self.assertEqual((a, b), (1, 2)) s = pack('10=150, 12=qee', qee=3) self.assertEqual(s, 'uint:10=150, uint:12=3') t = BitStream('100=5') self.assertEqual(t, 'uint:100=5') def testPackDefualtUintErrors(self): self.assertRaises(bitstring.CreationError, BitStream, '5=-1') def testPackingLongKeywordBitstring(self): s = pack('bits=b', b=BitStream(128000)) self.assertEqual(s, BitStream(128000)) def testPackingWithListFormat(self): f = ['bin', 'hex', 'uint:10'] a = pack(','.join(f), '00', '234', 100) b = pack(f, '00', '234', 100) self.assertEqual(a, b) class Unpack(unittest.TestCase): def testUnpack1(self): s = BitStream('uint:13=23, hex=e, bin=010, int:41=-554, 0o44332, se=-12, ue=4') s.pos = 11 a, b, c, d, e, f, g = s.unpack('uint:13, hex:4, bin:3, int:41, oct:15, se, ue') self.assertEqual(a, 23) self.assertEqual(b, 'e') self.assertEqual(c, '010') self.assertEqual(d, -554) self.assertEqual(e, '44332') self.assertEqual(f, -12) self.assertEqual(g, 4) self.assertEqual(s.pos, 11) def testUnpack2(self): s = BitStream('0xff, 0b000, uint:12=100') a, b, c = s.unpack('bits:8, bits, uint:12') self.assertEqual(type(s), BitStream) self.assertEqual(a, '0xff') self.assertEqual(type(s), BitStream) self.assertEqual(b, '0b000') self.assertEqual(c, 100) a, b = s.unpack(['bits:11', 'uint']) self.assertEqual(a, '0xff, 0b000') self.assertEqual(b, 100) def testUnpackNull(self): s = pack('0b1, , , 0xf,') a, b = s.unpack('bin:1,,,hex:4,') self.assertEqual(a, '1') self.assertEqual(b, 'f') class FromFile(unittest.TestCase): def testCreationFromFileOperations(self): s = BitStream(filename='smalltestfile') s.append('0xff') self.assertEqual(s.hex, '0123456789abcdefff') s = ConstBitStream(filename='smalltestfile') t = BitStream('0xff') + s self.assertEqual(t.hex, 'ff0123456789abcdef') s = BitStream(filename='smalltestfile') del s[:1] self.assertEqual((BitStream('0b0') + s).hex, '0123456789abcdef') s = BitStream(filename='smalltestfile') del s[:7 * 8] self.assertEqual(s.hex, 'ef') s = BitStream(filename='smalltestfile') s.insert('0xc', 4) self.assertEqual(s.hex, '0c123456789abcdef') s = BitStream(filename='smalltestfile') s.prepend('0xf') self.assertEqual(s.hex, 'f0123456789abcdef') s = BitStream(filename='smalltestfile') s.overwrite('0xaaa', 12) self.assertEqual(s.hex, '012aaa6789abcdef') s = BitStream(filename='smalltestfile') s.reverse() self.assertEqual(s.hex, 'f7b3d591e6a2c480') s = BitStream(filename='smalltestfile') del s[-60:] self.assertEqual(s.hex, '0') s = BitStream(filename='smalltestfile') del s[:60] self.assertEqual(s.hex, 'f') def testFileProperties(self): s = ConstBitStream(filename='smalltestfile') self.assertEqual(s.hex, '0123456789abcdef') self.assertEqual(s.uint, 81985529216486895) self.assertEqual(s.int, 81985529216486895) self.assertEqual(s.bin, '0000000100100011010001010110011110001001101010111100110111101111') self.assertEqual(s[:-1].oct, '002215053170465363367') s.bitpos = 0 self.assertEqual(s.read('se'), -72) s.bitpos = 0 self.assertEqual(s.read('ue'), 144) self.assertEqual(s.bytes, b'\x01\x23\x45\x67\x89\xab\xcd\xef') self.assertEqual(s.tobytes(), b'\x01\x23\x45\x67\x89\xab\xcd\xef') def testCreationFromFileWithLength(self): s = ConstBitStream(filename='test.m1v', length=32) self.assertEqual(s.length, 32) self.assertEqual(s.hex, '000001b3') s = ConstBitStream(filename='test.m1v', length=0) self.assertFalse(s) self.assertRaises(bitstring.CreationError, BitStream, filename='smalltestfile', length=65) self.assertRaises(bitstring.CreationError, ConstBitStream, filename='smalltestfile', length=64, offset=1) # self.assertRaises(bitstring.CreationError, ConstBitStream, filename='smalltestfile', offset=65) f = open('smalltestfile', 'rb') # self.assertRaises(bitstring.CreationError, ConstBitStream, auto=f, offset=65) self.assertRaises(bitstring.CreationError, ConstBitStream, auto=f, length=65) self.assertRaises(bitstring.CreationError, ConstBitStream, auto=f, offset=60, length=5) def testCreationFromFileWithOffset(self): a = BitStream(filename='test.m1v', offset=4) self.assertEqual(a.peek(4 * 8).hex, '00001b31') b = BitStream(filename='test.m1v', offset=28) self.assertEqual(b.peek(8).hex, '31') def testFileSlices(self): s = BitStream(filename='smalltestfile') self.assertEqual(s[-16:].hex, 'cdef') def testCreataionFromFileErrors(self): self.assertRaises(IOError, BitStream, filename='Idonotexist') def testFindInFile(self): s = BitStream(filename='test.m1v') self.assertTrue(s.find('0x160120')) self.assertEqual(s.bytepos, 4) s3 = s.read(3 * 8) self.assertEqual(s3.hex, '160120') s.bytepos = 0 self.assertTrue(s._pos == 0) self.assertTrue(s.find('0x0001b2')) self.assertEqual(s.bytepos, 13) def testHexFromFile(self): s = BitStream(filename='test.m1v') self.assertEqual(s[0:32].hex, '000001b3') self.assertEqual(s[-32:].hex, '000001b7') s.hex = '0x11' self.assertEqual(s.hex, '11') def testFileOperations(self): s1 = BitStream(filename='test.m1v') s2 = BitStream(filename='test.m1v') self.assertEqual(s1.read(32).hex, '000001b3') self.assertEqual(s2.read(32).hex, '000001b3') s1.bytepos += 4 self.assertEqual(s1.read(8).hex, '02') self.assertEqual(s2.read(5 * 8).hex, '1601208302') s1.pos = s1.len try: s1.pos += 1 self.assertTrue(False) except ValueError: pass def testFileBitGetting(self): s = ConstBitStream(filename='smalltestfile', offset=16, length=8) # 0x45 b = s[1] self.assertTrue(b) b = s.any(0, [-1, -2, -3]) self.assertTrue(b) b = s.all(0, [0, 1, 2]) self.assertFalse(b) def testVeryLargeFiles(self): # This uses an 11GB file which isn't distributed for obvious reasons # and so this test won't work for anyone except me! try: s = ConstBitStream(filename='11GB.mkv') except IOError: return self.assertEqual(s.len, 11743020505 * 8) self.assertEqual(s[1000000000:1000000100].hex, 'bdef7335d4545f680d669ce24') self.assertEqual(s[-4::8].hex, 'bbebf7a1') class CreationErrors(unittest.TestCase): def testIncorrectBinAssignment(self): s = BitStream() self.assertRaises(bitstring.CreationError, s._setbin_safe, '0010020') def testIncorrectHexAssignment(self): s = BitStream() self.assertRaises(bitstring.CreationError, s._sethex, '0xabcdefg') class Length(unittest.TestCase): def testLengthZero(self): self.assertEqual(BitStream('').len, 0) def testLength(self): self.assertEqual(BitStream('0x80').len, 8) def testLengthErrors(self): #TODO: Lots of new checks, for various inits which now disallow length and offset pass #self.assertRaises(ValueError, BitStream, bin='111', length=-1) #self.assertRaises(ValueError, BitStream, bin='111', length=4) def testOffsetLengthError(self): self.assertRaises(bitstring.CreationError, BitStream, hex='0xffff', offset=-1) class SimpleConversions(unittest.TestCase): def testConvertToUint(self): self.assertEqual(BitStream('0x10').uint, 16) self.assertEqual(BitStream('0b000111').uint, 7) def testConvertToInt(self): self.assertEqual(BitStream('0x10').int, 16) self.assertEqual(BitStream('0b11110').int, -2) def testConvertToHex(self): self.assertEqual(BitStream(bytes=b'\x00\x12\x23\xff').hex, '001223ff') s = BitStream('0b11111') self.assertRaises(bitstring.InterpretError, s._gethex) class Empty(unittest.TestCase): def testEmptyBitstring(self): s = BitStream() self.assertRaises(bitstring.ReadError, s.read, 1) self.assertEqual(s.bin, '') self.assertEqual(s.hex, '') self.assertRaises(bitstring.InterpretError, s._getint) self.assertRaises(bitstring.InterpretError, s._getuint) self.assertFalse(s) def testNonEmptyBitStream(self): s = BitStream(bin='0') self.assertFalse(not s.len) class Position(unittest.TestCase): def testBitPosition(self): s = BitStream(bytes=b'\x00\x00\x00') self.assertEqual(s.bitpos, 0) s.read(5) self.assertEqual(s.pos, 5) s.pos = s.len self.assertRaises(bitstring.ReadError, s.read, 1) def testBytePosition(self): s = BitStream(bytes=b'\x00\x00\x00') self.assertEqual(s.bytepos, 0) s.read(10) self.assertRaises(bitstring.ByteAlignError, s._getbytepos) s.read(6) self.assertEqual(s.bytepos, 2) def testSeekToBit(self): s = BitStream(bytes=b'\x00\x00\x00\x00\x00\x00') s.bitpos = 0 self.assertEqual(s.bitpos, 0) self.assertRaises(ValueError, s._setbitpos, -1) self.assertRaises(ValueError, s._setbitpos, 6 * 8 + 1) s.bitpos = 6 * 8 self.assertEqual(s.bitpos, 6 * 8) def testSeekToByte(self): s = BitStream(bytes=b'\x00\x00\x00\x00\x00\xab') s.bytepos = 5 self.assertEqual(s.read(8).hex, 'ab') def testAdvanceBitsAndBytes(self): s = BitStream(bytes=b'\x00\x00\x00\x00\x00\x00\x00\x00') s.pos += 5 self.assertEqual(s.pos, 5) s.bitpos += 16 self.assertEqual(s.pos, 2 * 8 + 5) s.pos -= 8 self.assertEqual(s.pos, 8 + 5) def testRetreatBitsAndBytes(self): a = BitStream(length=100) a.pos = 80 a.bytepos -= 5 self.assertEqual(a.bytepos, 5) a.pos -= 5 self.assertEqual(a.pos, 35) class Offset(unittest.TestCase): def testOffset1(self): s = BitStream(bytes=b'\x00\x1b\x3f', offset=4) self.assertEqual(s.read(8).bin, '00000001') self.assertEqual(s.length, 20) def testOffset2(self): s1 = BitStream(bytes=b'\xf1\x02\x04') s2 = BitStream(bytes=b'\xf1\x02\x04', length=23) for i in [1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0, 7, 3, 5, 1, 4]: s1._datastore = offsetcopy(s1._datastore, i) self.assertEqual(s1.hex, 'f10204') s2._datastore = offsetcopy(s2._datastore, i) self.assertEqual(s2.bin, '11110001000000100000010') class Append(unittest.TestCase): def testAppend(self): s1 = BitStream('0b00000') s1.append(BitStream(bool=True)) self.assertEqual(s1.bin, '000001') self.assertEqual((BitStream('0x0102') + BitStream('0x0304')).hex, '01020304') def testAppendSameBitstring(self): s1 = BitStream('0xf0')[:6] s1.append(s1) self.assertEqual(s1.bin, '111100111100') def testAppendWithOffset(self): s = BitStream(bytes=b'\x28\x28', offset=1) s.append('0b0') self.assertEqual(s.hex, '5050') class ByteAlign(unittest.TestCase): def testByteAlign(self): s = BitStream(hex='0001ff23') s.bytealign() self.assertEqual(s.bytepos, 0) s.pos += 11 s.bytealign() self.assertEqual(s.bytepos, 2) s.pos -= 10 s.bytealign() self.assertEqual(s.bytepos, 1) def testByteAlignWithOffset(self): s = BitStream(hex='0112233') s._datastore = offsetcopy(s._datastore, 3) bitstoalign = s.bytealign() self.assertEqual(bitstoalign, 0) self.assertEqual(s.read(5).bin, '00001') def testInsertByteAligned(self): s = BitStream('0x0011') s.insert(BitStream('0x22'), 8) self.assertEqual(s.hex, '002211') s = BitStream(0) s.insert(BitStream(bin='101'), 0) self.assertEqual(s.bin, '101') class Truncate(unittest.TestCase): def testTruncateStart(self): s = BitStream('0b1') del s[:1] self.assertFalse(s) s = BitStream(hex='1234') self.assertEqual(s.hex, '1234') del s[:4] self.assertEqual(s.hex, '234') del s[:9] self.assertEqual(s.bin, '100') del s[:2] self.assertEqual(s.bin, '0') self.assertEqual(s.len, 1) del s[:1] self.assertFalse(s) def testTruncateEnd(self): s = BitStream('0b1') del s[-1:] self.assertFalse(s) s = BitStream(bytes=b'\x12\x34') self.assertEqual(s.hex, '1234') del s[-4:] self.assertEqual(s.hex, '123') del s[-9:] self.assertEqual(s.bin, '000') del s[-3:] self.assertFalse(s) s = BitStream('0b001') del s[:2] del s[-1:] self.assertFalse(s) class Slice(unittest.TestCase): def testByteAlignedSlice(self): s = BitStream(hex='0x123456') self.assertEqual(s[8:16].hex, '34') s = s[8:24] self.assertEqual(s.len, 16) self.assertEqual(s.hex, '3456') s = s[0:8] self.assertEqual(s.hex, '34') s.hex = '0x123456' self.assertEqual(s[8:24][0:8].hex, '34') def testSlice(self): s = BitStream(bin='000001111100000') s1 = s[0:5] s2 = s[5:10] s3 = s[10:15] self.assertEqual(s1.bin, '00000') self.assertEqual(s2.bin, '11111') self.assertEqual(s3.bin, '00000') class Insert(unittest.TestCase): def testInsert(self): s1 = BitStream(hex='0x123456') s2 = BitStream(hex='0xff') s1.bytepos = 1 s1.insert(s2) self.assertEqual(s1.bytepos, 2) self.assertEqual(s1.hex, '12ff3456') s1.insert('0xee', 24) self.assertEqual(s1.hex, '12ff34ee56') self.assertEqual(s1.bitpos, 32) self.assertRaises(ValueError, s1.insert, '0b1', -1000) self.assertRaises(ValueError, s1.insert, '0b1', 1000) def testInsertNull(self): s = BitStream(hex='0x123').insert(BitStream(), 3) self.assertEqual(s.hex, '123') def testInsertBits(self): one = BitStream(bin='1') zero = BitStream(bin='0') s = BitStream(bin='00') s.insert(one, 0) self.assertEqual(s.bin, '100') s.insert(zero, 0) self.assertEqual(s.bin, '0100') s.insert(one, s.len) self.assertEqual(s.bin, '01001') s.insert(s, 2) self.assertEqual(s.bin, '0101001001') class Resetting(unittest.TestCase): def testSetHex(self): s = BitStream() s.hex = '0' self.assertEqual(s.hex, '0') s.hex = '0x010203045' self.assertEqual(s.hex, '010203045') self.assertRaises(bitstring.CreationError, s._sethex, '0x002g') def testSetBin(self): s = BitStream(bin="000101101") self.assertEqual(s.bin, '000101101') self.assertEqual(s.len, 9) s.bin = '0' self.assertEqual(s.bin, '0') self.assertEqual(s.len, 1) def testSetEmptyBin(self): s = BitStream(hex='0x000001b3') s.bin = '' self.assertEqual(s.len, 0) self.assertEqual(s.bin, '') def testSetInvalidBin(self): s = BitStream() self.assertRaises(bitstring.CreationError, s._setbin_safe, '00102') class Overwriting(unittest.TestCase): def testOverwriteBit(self): s = BitStream(bin='0') s.overwrite(BitStream(bin='1'), 0) self.assertEqual(s.bin, '1') def testOverwriteLimits(self): s = BitStream(bin='0b11111') s.overwrite(BitStream(bin='000'), 0) self.assertEqual(s.bin, '00011') s.overwrite('0b000', 2) self.assertEqual(s.bin, '00000') def testOverwriteNull(self): s = BitStream(hex='342563fedec') s2 = BitStream(s) s.overwrite(BitStream(bin=''), 23) self.assertEqual(s.bin, s2.bin) def testOverwritePosition(self): s1 = BitStream(hex='0123456') s2 = BitStream(hex='ff') s1.bytepos = 1 s1.overwrite(s2) self.assertEqual((s1.hex, s1.bytepos), ('01ff456', 2)) s1.overwrite('0xff', 0) self.assertEqual((s1.hex, s1.bytepos), ('ffff456', 1)) def testOverwriteWithSelf(self): s = BitStream('0x123') s.overwrite(s) self.assertEqual(s, '0x123') class Split(unittest.TestCase): def testSplitByteAlignedCornerCases(self): s = BitStream() bsl = s.split(BitStream(hex='0xff')) self.assertEqual(next(bsl).hex, '') self.assertRaises(StopIteration, next, bsl) s = BitStream(hex='aabbcceeddff') delimiter = BitStream() bsl = s.split(delimiter) self.assertRaises(ValueError, next, bsl) delimiter = BitStream(hex='11') bsl = s.split(delimiter) self.assertEqual(next(bsl).hex, s.hex) def testSplitByteAligned(self): s = BitStream(hex='0x1234aa1234bbcc1234ffff') delimiter = BitStream(hex='1234') bsl = s.split(delimiter) self.assertEqual([b.hex for b in bsl], ['', '1234aa', '1234bbcc', '1234ffff']) self.assertEqual(s.pos, 0) def testSplitByteAlignedWithIntialBytes(self): s = BitStream(hex='aa471234fedc43 47112233 47 4723 472314') delimiter = BitStream(hex='47') s.find(delimiter) self.assertEqual(s.bytepos, 1) bsl = s.split(delimiter, start=0) self.assertEqual([b.hex for b in bsl], ['aa', '471234fedc43', '47112233', '47', '4723', '472314']) self.assertEqual(s.bytepos, 1) def testSplitByteAlignedWithOverlappingDelimiter(self): s = BitStream(hex='aaffaaffaaffaaffaaff') bsl = s.split(BitStream(hex='aaffaa')) self.assertEqual([b.hex for b in bsl], ['', 'aaffaaff', 'aaffaaffaaff']) class Adding(unittest.TestCase): def testAdding(self): s1 = BitStream(hex='0x0102') s2 = BitStream(hex='0x0304') s3 = s1 + s2 self.assertEqual(s1.hex, '0102') self.assertEqual(s2.hex, '0304') self.assertEqual(s3.hex, '01020304') s3 += s1 self.assertEqual(s3.hex, '010203040102') self.assertEqual(s2[9:16].bin, '0000100') self.assertEqual(s1[0:9].bin, '000000010') s4 = BitStream(bin='000000010') +\ BitStream(bin='0000100') self.assertEqual(s4.bin, '0000000100000100') s2p = s2[9:16] s1p = s1[0:9] s5p = s1p + s2p s5 = s1[0:9] + s2[9:16] self.assertEqual(s5.bin, '0000000100000100') def testMoreAdding(self): s = BitStream(bin='00') + BitStream(bin='') + BitStream(bin='11') self.assertEqual(s.bin, '0011') s = '0b01' s += BitStream('0b11') self.assertEqual(s.bin, '0111') s = BitStream('0x00') t = BitStream('0x11') s += t self.assertEqual(s.hex, '0011') self.assertEqual(t.hex, '11') s += s self.assertEqual(s.hex, '00110011') def testRadd(self): s = '0xff' + BitStream('0xee') self.assertEqual(s.hex, 'ffee') def testTruncateAsserts(self): s = BitStream('0x001122') s.bytepos = 2 del s[-s.len:] self.assertEqual(s.bytepos, 0) s.append('0x00') s.append('0x1122') s.bytepos = 2 del s[:s.len] self.assertEqual(s.bytepos, 0) s.append('0x00') def testOverwriteErrors(self): s = BitStream(bin='11111') self.assertRaises(ValueError, s.overwrite, BitStream(bin='1'), -10) self.assertRaises(ValueError, s.overwrite, BitStream(bin='1'), 6) self.assertRaises(ValueError, s.overwrite, BitStream(bin='11111'), 1) def testDeleteBits(self): s = BitStream(bin='000111100000') s.bitpos = 4 del s[4:8] self.assertEqual(s.bin, '00010000') del s[4:1004] self.assertTrue(s.bin, '0001') def testDeleteBitsWithPosition(self): s = BitStream(bin='000111100000') del s[4:8] self.assertEqual(s.bin, '00010000') def testDeleteBytes(self): s = BitStream('0x00112233') del s[8:8] self.assertEqual(s.hex, '00112233') self.assertEqual(s.pos, 0) del s[8:16] self.assertEqual(s.hex, '002233') self.assertEqual(s.bytepos, 0) del s[:24] self.assertFalse(s) self.assertEqual(s.pos, 0) def testGetItemWithPositivePosition(self): s = BitStream(bin='0b1011') self.assertEqual(s[0], True) self.assertEqual(s[1], False) self.assertEqual(s[2], True) self.assertEqual(s[3], True) self.assertRaises(IndexError, s.__getitem__, 4) def testGetItemWithNegativePosition(self): s = BitStream(bin='1011') self.assertEqual(s[-1], True) self.assertEqual(s[-2], True) self.assertEqual(s[-3], False) self.assertEqual(s[-4], True) self.assertRaises(IndexError, s.__getitem__, -5) def testSlicing(self): s = ConstBitStream(hex='0123456789') self.assertEqual(s[0:8].hex, '01') self.assertFalse(s[0:0]) self.assertFalse(s[23:20]) self.assertEqual(s[8:12].bin, '0010') self.assertEqual(s[32:80], '0x89') def testNegativeSlicing(self): s = ConstBitStream(hex='012345678') self.assertEqual(s[:-8].hex, '0123456') self.assertEqual(s[-16:-8].hex, '56') self.assertEqual(s[-24:].hex, '345678') self.assertEqual(s[-1000:-24], '0x012') def testLen(self): s = BitStream() self.assertEqual(len(s), 0) s.append(BitStream(bin='001')) self.assertEqual(len(s), 3) def testJoin(self): s1 = BitStream(bin='0') s2 = BitStream(bin='1') s3 = BitStream(bin='000') s4 = BitStream(bin='111') strings = [s1, s2, s1, s3, s4] s = BitStream().join(strings) self.assertEqual(s.bin, '010000111') def testJoin2(self): s1 = BitStream(hex='00112233445566778899aabbccddeeff') s2 = BitStream(bin='0b000011') bsl = [s1[0:32], s1[4:12], s2, s2, s2, s2] s = ConstBitStream().join(bsl) self.assertEqual(s.hex, '00112233010c30c3') bsl = [BitStream(uint=j, length=12) for j in range(10) for i in range(10)] s = BitStream().join(bsl) self.assertEqual(s.length, 1200) def testPos(self): s = BitStream(bin='1') self.assertEqual(s.bitpos, 0) s.read(1) self.assertEqual(s.bitpos, 1) def testWritingData(self): strings = [BitStream(bin=x) for x in ['0', '001', '0011010010', '010010', '1011']] s = BitStream().join(strings) s2 = BitStream(bytes=s.bytes) self.assertEqual(s2.bin, '000100110100100100101011') s2.append(BitStream(bin='1')) s3 = BitStream(bytes=s2.tobytes()) self.assertEqual(s3.bin, '00010011010010010010101110000000') def testWritingDataWithOffsets(self): s1 = BitStream(bytes=b'\x10') s2 = BitStream(bytes=b'\x08\x00', length=8, offset=1) s3 = BitStream(bytes=b'\x04\x00', length=8, offset=2) self.assertTrue(s1 == s2) self.assertTrue(s2 == s3) self.assertTrue(s1.bytes == s2.bytes) self.assertTrue(s2.bytes == s3.bytes) def testVariousThings1(self): hexes = ['12345678', '87654321', 'ffffffffff', 'ed', '12ec'] bins = ['001010', '1101011', '0010000100101110110110', '11', '011'] bsl = [] for (hex, bin) in list(zip(hexes, bins)) * 5: bsl.append(BitStream(hex=hex)) bsl.append(BitStream(bin=bin)) s = BitStream().join(bsl) for (hex, bin) in list(zip(hexes, bins)) * 5: h = s.read(4 * len(hex)) b = s.read(len(bin)) self.assertEqual(h.hex, hex) self.assertEqual(b.bin, bin) def testVariousThings2(self): s1 = BitStream(hex="0x1f08")[:13] self.assertEqual(s1.bin, '0001111100001') s2 = BitStream(bin='0101') self.assertEqual(s2.bin, '0101') s1.append(s2) self.assertEqual(s1.length, 17) self.assertEqual(s1.bin, '00011111000010101') s1 = s1[3:8] self.assertEqual(s1.bin, '11111') def testVariousThings3(self): s1 = BitStream(hex='0x012480ff')[2:27] s2 = s1 + s1 self.assertEqual(s2.length, 50) s3 = s2[0:25] s4 = s2[25:50] self.assertEqual(s3.bin, s4.bin) def testPeekBit(self): s = BitStream(bin='01') self.assertEqual(s.peek(1), [0]) self.assertEqual(s.peek(1), [0]) self.assertEqual(s.read(1), [0]) self.assertEqual(s.peek(1), [1]) self.assertEqual(s.peek(1), [1]) s = BitStream(bytes=b'\x1f', offset=3) self.assertEqual(s.len, 5) self.assertEqual(s.peek(5).bin, '11111') self.assertEqual(s.peek(5).bin, '11111') s.pos += 1 self.assertRaises(bitstring.ReadError, s.peek, 5) s = BitStream(hex='001122334455') self.assertEqual(s.peek(8).hex, '00') self.assertEqual(s.read(8).hex, '00') s.pos += 33 self.assertRaises(bitstring.ReadError, s.peek, 8) s = BitStream(hex='001122334455') self.assertEqual(s.peek(8 * 2).hex, '0011') self.assertEqual(s.read(8 * 3).hex, '001122') self.assertEqual(s.peek(8 * 3).hex, '334455') self.assertRaises(bitstring.ReadError, s.peek, 25) def testAdvanceBit(self): s = BitStream(hex='0xff') s.bitpos = 6 s.pos += 1 self.assertEqual(s.bitpos, 7) s.bitpos += 1 try: s.pos += 1 self.assertTrue(False) except ValueError: pass def testAdvanceByte(self): s = BitStream(hex='0x010203') s.bytepos += 1 self.assertEqual(s.bytepos, 1) s.bytepos += 1 self.assertEqual(s.bytepos, 2) s.bytepos += 1 try: s.bytepos += 1 self.assertTrue(False) except ValueError: pass def testRetreatBit(self): s = BitStream(hex='0xff') try: s.pos -= 1 self.assertTrue(False) except ValueError: pass s.pos = 5 s.pos -= 1 self.assertEqual(s.pos, 4) def testRetreatByte(self): s = BitStream(hex='0x010203') try: s.bytepos -= 1 self.assertTrue(False) except ValueError: pass s.bytepos = 3 s.bytepos -= 1 self.assertEqual(s.bytepos, 2) self.assertEqual(s.read(8).hex, '03') def testCreationByAuto(self): s = BitStream('0xff') self.assertEqual(s.hex, 'ff') s = BitStream('0b00011') self.assertEqual(s.bin, '00011') self.assertRaises(bitstring.CreationError, BitStream, 'hello') s1 = BitStream(bytes=b'\xf5', length=3, offset=5) s2 = BitStream(s1, length=1, offset=1) self.assertEqual(s2, '0b0') s = BitStream(bytes=b'\xff', offset=2) t = BitStream(s, offset=2) self.assertEqual(t, '0b1111') self.assertRaises(TypeError, BitStream, auto=1.2) def testCreationByAuto2(self): s = BitStream('bin=001') self.assertEqual(s.bin, '001') s = BitStream('oct=0o007') self.assertEqual(s.oct, '007') s = BitStream('hex=123abc') self.assertEqual(s, '0x123abc') s = BitStream('bin:2=01') self.assertEqual(s, '0b01') for s in ['bin:1=01', 'bits:4=0b1', 'oct:3=000', 'hex:4=0x1234']: self.assertRaises(bitstring.CreationError, BitStream, s) def testInsertUsingAuto(self): s = BitStream('0xff') s.insert('0x00', 4) self.assertEqual(s.hex, 'f00f') self.assertRaises(ValueError, s.insert, 'ff') def testOverwriteUsingAuto(self): s = BitStream('0x0110') s.overwrite('0b1') self.assertEqual(s.hex, '8110') s.overwrite('') self.assertEqual(s.hex, '8110') self.assertRaises(ValueError, s.overwrite, '0bf') def testFindUsingAuto(self): s = BitStream('0b000000010100011000') self.assertTrue(s.find('0b101')) self.assertEqual(s.pos, 7) def testFindbytealignedUsingAuto(self): s = BitStream('0x00004700') self.assertTrue(s.find('0b01000111', bytealigned=True)) self.assertEqual(s.bytepos, 2) def testAppendUsingAuto(self): s = BitStream('0b000') s.append('0b111') self.assertEqual(s.bin, '000111') s.append('0b0') self.assertEqual(s.bin, '0001110') def testSplitByteAlignedUsingAuto(self): s = BitStream('0x000143563200015533000123') sections = s.split('0x0001') self.assertEqual(next(sections).hex, '') self.assertEqual(next(sections).hex, '0001435632') self.assertEqual(next(sections).hex, '00015533') self.assertEqual(next(sections).hex, '000123') self.assertRaises(StopIteration, next, sections) def testSplitByteAlignedWithSelf(self): s = BitStream('0x1234') sections = s.split(s) self.assertEqual(next(sections).hex, '') self.assertEqual(next(sections).hex, '1234') self.assertRaises(StopIteration, next, sections) def testPrepend(self): s = BitStream('0b000') s.prepend('0b11') self.assertEqual(s.bin, '11000') s.prepend(s) self.assertEqual(s.bin, '1100011000') s.prepend('') self.assertEqual(s.bin, '1100011000') def testNullSlice(self): s = BitStream('0x111') t = s[1:1] self.assertEqual(t._datastore.bytelength, 0) def testMultipleAutos(self): s = BitStream('0xa') s.prepend('0xf') s.append('0xb') self.assertEqual(s, '0xfab') s.prepend(s) s.append('0x100') s.overwrite('0x5', 4) self.assertEqual(s, '0xf5bfab100') def testReverse(self): s = BitStream('0b0011') s.reverse() self.assertEqual(s.bin, '1100') s = BitStream('0b10') s.reverse() self.assertEqual(s.bin, '01') s = BitStream() s.reverse() self.assertEqual(s.bin, '') def testInitWithConcatenatedStrings(self): s = BitStream('0xff 0Xee 0xd 0xcc') self.assertEqual(s.hex, 'ffeedcc') s = BitStream('0b0 0B111 0b001') self.assertEqual(s.bin, '0111001') s += '0b1' + '0B1' self.assertEqual(s.bin, '011100111') s = BitStream(hex='ff0xee') self.assertEqual(s.hex, 'ffee') s = BitStream(bin='000b0b11') self.assertEqual(s.bin, '0011') s = BitStream(' 0o123 0O 7 0 o1') self.assertEqual(s.oct, '12371') s += ' 0 o 332' self.assertEqual(s.oct, '12371332') def testEquals(self): s1 = BitStream('0b01010101') s2 = BitStream('0b01010101') self.assertTrue(s1 == s2) s3 = BitStream() s4 = BitStream() self.assertTrue(s3 == s4) self.assertFalse(s3 != s4) s5 = BitStream(bytes=b'\xff', offset=2, length=3) s6 = BitStream('0b111') self.assertTrue(s5 == s6) class A(object): pass self.assertFalse(s5 == A()) def testLargeEquals(self): s1 = BitStream(1000000) s2 = BitStream(1000000) s1.set(True, [-1, 55, 53214, 534211, 999999]) s2.set(True, [-1, 55, 53214, 534211, 999999]) self.assertEqual(s1, s2) s1.set(True, 800000) self.assertNotEqual(s1, s2) def testNotEquals(self): s1 = BitStream('0b0') s2 = BitStream('0b1') self.assertTrue(s1 != s2) self.assertFalse(s1 != BitStream('0b0')) def testEqualityWithAutoInitialised(self): a = BitStream('0b00110111') self.assertTrue(a == '0b00110111') self.assertTrue(a == '0x37') self.assertTrue('0b0011 0111' == a) self.assertTrue('0x3 0x7' == a) self.assertFalse(a == '0b11001000') self.assertFalse('0x3737' == a) def testInvertSpecialMethod(self): s = BitStream('0b00011001') self.assertEqual((~s).bin, '11100110') self.assertEqual((~BitStream('0b0')).bin, '1') self.assertEqual((~BitStream('0b1')).bin, '0') self.assertTrue(~~s == s) def testInvertBitPosition(self): s = ConstBitStream('0xefef') s.pos = 8 t = ~s self.assertEqual(s.pos, 8) self.assertEqual(t.pos, 0) def testInvertSpecialMethodErrors(self): s = BitStream() self.assertRaises(bitstring.Error, s.__invert__) def testJoinWithAuto(self): s = BitStream().join(['0xf', '0b00', BitStream(bin='11')]) self.assertEqual(s, '0b11110011') def testAutoBitStringCopy(self): s = BitStream('0xabcdef') t = BitStream(s) self.assertEqual(t.hex, 'abcdef') del s[-8:] self.assertEqual(t.hex, 'abcdef') class Multiplication(unittest.TestCase): def testMultiplication(self): a = BitStream('0xff') b = a * 8 self.assertEqual(b, '0xffffffffffffffff') b = 4 * a self.assertEqual(b, '0xffffffff') self.assertTrue(1 * a == a * 1 == a) c = a * 0 self.assertFalse(c) a *= 3 self.assertEqual(a, '0xffffff') a *= 0 self.assertFalse(a) one = BitStream('0b1') zero = BitStream('0b0') mix = one * 2 + 3 * zero + 2 * one * 2 self.assertEqual(mix, '0b110001111') q = BitStream() q *= 143 self.assertFalse(q) q += [True, True, False] q.pos += 2 q *= 0 self.assertFalse(q) self.assertEqual(q.bitpos, 0) def testMultiplicationWithFiles(self): a = BitStream(filename='test.m1v') b = a.len a *= 3 self.assertEqual(a.len, 3 * b) def testMultiplicationErrors(self): a = BitStream('0b1') b = BitStream('0b0') self.assertRaises(ValueError, a.__mul__, -1) self.assertRaises(ValueError, a.__imul__, -1) self.assertRaises(ValueError, a.__rmul__, -1) self.assertRaises(TypeError, a.__mul__, 1.2) self.assertRaises(TypeError, a.__rmul__, b) self.assertRaises(TypeError, a.__imul__, b) def testFileAndMemEquivalence(self): a = ConstBitStream(filename='smalltestfile') b = BitStream(filename='smalltestfile') self.assertTrue(isinstance(a._datastore._rawarray, bitstring.MmapByteArray)) self.assertTrue(isinstance(b._datastore._rawarray, bytearray)) self.assertEqual(a._datastore.getbyte(0), b._datastore.getbyte(0)) self.assertEqual(a._datastore.getbyteslice(1, 5), bytearray(b._datastore.getbyteslice(1, 5))) class BitWise(unittest.TestCase): def testBitwiseAnd(self): a = BitStream('0b01101') b = BitStream('0b00110') self.assertEqual((a & b).bin, '00100') self.assertEqual((a & '0b11111'), a) self.assertRaises(ValueError, a.__and__, '0b1') self.assertRaises(ValueError, b.__and__, '0b110111111') c = BitStream('0b0011011') c.pos = 4 d = c & '0b1111000' self.assertEqual(d.pos, 0) self.assertEqual(d.bin, '0011000') d = '0b1111000' & c self.assertEqual(d.bin, '0011000') def testBitwiseOr(self): a = BitStream('0b111001001') b = BitStream('0b011100011') self.assertEqual((a | b).bin, '111101011') self.assertEqual((a | '0b000000000'), a) self.assertRaises(ValueError, a.__or__, '0b0000') self.assertRaises(ValueError, b.__or__, a + '0b1') a = '0xff00' | BitStream('0x00f0') self.assertEqual(a.hex, 'fff0') def testBitwiseXor(self): a = BitStream('0b111001001') b = BitStream('0b011100011') self.assertEqual((a ^ b).bin, '100101010') self.assertEqual((a ^ '0b111100000').bin, '000101001') self.assertRaises(ValueError, a.__xor__, '0b0000') self.assertRaises(ValueError, b.__xor__, a + '0b1') a = '0o707' ^ BitStream('0o777') self.assertEqual(a.oct, '070') class Split(unittest.TestCase): def testSplit(self): a = BitStream('0b0 010100111 010100 0101 010') a.pos = 20 subs = [i.bin for i in a.split('0b010')] self.assertEqual(subs, ['0', '010100111', '010100', '0101', '010']) self.assertEqual(a.pos, 20) def testSplitCornerCases(self): a = BitStream('0b000000') bsl = a.split('0b1', False) self.assertEqual(next(bsl), a) self.assertRaises(StopIteration, next, bsl) b = BitStream() bsl = b.split('0b001', False) self.assertFalse(next(bsl)) self.assertRaises(StopIteration, next, bsl) def testSplitErrors(self): a = BitStream('0b0') b = a.split('', False) self.assertRaises(ValueError, next, b) def testSliceWithOffset(self): a = BitStream(bytes=b'\x00\xff\x00', offset=7) b = a[7:12] self.assertEqual(b.bin, '11000') def testSplitWithMaxsplit(self): a = BitStream('0xaabbccbbccddbbccddee') self.assertEqual(len(list(a.split('0xbb', bytealigned=True))), 4) bsl = list(a.split('0xbb', count=1, bytealigned=True)) self.assertEqual((len(bsl), bsl[0]), (1, '0xaa')) bsl = list(a.split('0xbb', count=2, bytealigned=True)) self.assertEqual(len(bsl), 2) self.assertEqual(bsl[0], '0xaa') self.assertEqual(bsl[1], '0xbbcc') def testSplitMore(self): s = BitStream('0b1100011001110110') for i in range(10): a = list(s.split('0b11', False, count=i)) b = list(s.split('0b11', False))[:i] self.assertEqual(a, b) b = s.split('0b11', count=-1) self.assertRaises(ValueError, next, b) def testSplitStartbit(self): a = BitStream('0b0010101001000000001111') bsl = a.split('0b001', bytealigned=False, start=1) self.assertEqual([x.bin for x in bsl], ['010101', '001000000', '001111']) b = a.split('0b001', start=-100) self.assertRaises(ValueError, next, b) b = a.split('0b001', start=23) self.assertRaises(ValueError, next, b) b = a.split('0b1', start=10, end=9) self.assertRaises(ValueError, next, b) def testSplitStartbitByteAligned(self): a = BitStream('0x00ffffee') bsl = list(a.split('0b111', start=9, bytealigned=True)) self.assertEqual([x.bin for x in bsl], ['1111111', '11111111', '11101110']) def testSplitEndbit(self): a = BitStream('0b000010001001011') bsl = list(a.split('0b1', bytealigned=False, end=14)) self.assertEqual([x.bin for x in bsl], ['0000', '1000', '100', '10', '1']) self.assertEqual(list(a[4:12].split('0b0', False)), list(a.split('0b0', start=4, end=12))) # Shouldn't raise ValueError bsl = list(a.split('0xffee', end=15)) # Whereas this one will when we call next() bsl = a.split('0xffee', end=16) self.assertRaises(ValueError, next, bsl) def testSplitEndbitByteAligned(self): a = BitStream('0xff00ff')[:22] bsl = list(a.split('0b 0000 0000 111', end=19)) self.assertEqual([x.bin for x in bsl], ['11111111', '00000000111']) bsl = list(a.split('0b 0000 0000 111', end=18)) self.assertEqual([x.bin for x in bsl], ['111111110000000011']) def testSplitMaxSplit(self): a = BitStream('0b1' * 20) for i in range(10): bsl = list(a.split('0b1', count=i)) self.assertEqual(len(bsl), i) ####################### def testPositionInSlice(self): a = BitStream('0x00ffff00') a.bytepos = 2 b = a[8:24] self.assertEqual(b.bytepos, 0) def testFindByteAlignedWithBits(self): a = BitStream('0x00112233445566778899') a.find('0b0001', bytealigned=True) self.assertEqual(a.bitpos, 8) def testFindStartbitNotByteAligned(self): a = BitStream('0b0010000100') found = a.find('0b1', start=4) self.assertEqual((found, a.bitpos), ((7,), 7)) found = a.find('0b1', start=2) self.assertEqual((found, a.bitpos), ((2,), 2)) found = a.find('0b1', bytealigned=False, start=8) self.assertEqual((found, a.bitpos), ((), 2)) def testFindEndbitNotByteAligned(self): a = BitStream('0b0010010000') found = a.find('0b1', bytealigned=False, end=2) self.assertEqual((found, a.bitpos), ((), 0)) found = a.find('0b1', end=3) self.assertEqual((found, a.bitpos), ((2,), 2)) found = a.find('0b1', bytealigned=False, start=3, end=5) self.assertEqual((found, a.bitpos), ((), 2)) found = a.find('0b1', start=3, end=6) self.assertEqual((found[0], a.bitpos), (5, 5)) def testFindStartbitByteAligned(self): a = BitStream('0xff001122ff0011ff') a.pos = 40 found = a.find('0x22', start=23, bytealigned=True) self.assertEqual((found, a.bytepos), ((24,), 3)) a.bytepos = 4 found = a.find('0x22', start=24, bytealigned=True) self.assertEqual((found, a.bytepos), ((24,), 3)) found = a.find('0x22', start=25, bytealigned=True) self.assertEqual((found, a.pos), ((), 24)) found = a.find('0b111', start=40, bytealigned=True) self.assertEqual((found, a.pos), ((56,), 56)) def testFindEndbitByteAligned(self): a = BitStream('0xff001122ff0011ff') found = a.find('0x22', end=31, bytealigned=True) self.assertFalse(found) self.assertEqual(a.pos, 0) found = a.find('0x22', end=32, bytealigned=True) self.assertTrue(found) self.assertEqual(a.pos, 24) self.assertEqual(found[0], 24) def testFindStartEndbitErrors(self): a = BitStream('0b00100') self.assertRaises(ValueError, a.find, '0b1', bytealigned=False, start=-100) self.assertRaises(ValueError, a.find, '0b1', end=6) self.assertRaises(ValueError, a.find, '0b1', start=4, end=3) b = BitStream('0x0011223344') self.assertRaises(ValueError, a.find, '0x22', bytealigned=True, start=-100) self.assertRaises(ValueError, a.find, '0x22', end=41, bytealigned=True) def testPrependAndAppendAgain(self): c = BitStream('0x1122334455667788') c.bitpos = 40 c.prepend('0b1') self.assertEqual(c.bitpos, 41) c = BitStream() c.prepend('0x1234') self.assertEqual(c.bytepos, 2) c = BitStream() c.append('0x1234') self.assertEqual(c.bytepos, 0) s = BitStream(bytes=b'\xff\xff', offset=2) self.assertEqual(s.length, 14) t = BitStream(bytes=b'\x80', offset=1, length=2) s.prepend(t) self.assertEqual(s, '0x3fff') def testFindAll(self): a = BitStream('0b11111') p = a.findall('0b1') self.assertEqual(list(p), [0, 1, 2, 3, 4]) p = a.findall('0b11') self.assertEqual(list(p), [0, 1, 2, 3]) p = a.findall('0b10') self.assertEqual(list(p), []) a = BitStream('0x4733eeff66554747335832434547') p = a.findall('0x47', bytealigned=True) self.assertEqual(list(p), [0, 6 * 8, 7 * 8, 13 * 8]) p = a.findall('0x4733', bytealigned=True) self.assertEqual(list(p), [0, 7 * 8]) a = BitStream('0b1001001001001001001') p = a.findall('0b1001', bytealigned=False) self.assertEqual(list(p), [0, 3, 6, 9, 12, 15]) self.assertEqual(a.pos, 15) def testFindAllGenerator(self): a = BitStream('0xff1234512345ff1234ff12ff') p = a.findall('0xff', bytealigned=True) self.assertEqual(next(p), 0) self.assertEqual(next(p), 6 * 8) self.assertEqual(next(p), 9 * 8) self.assertEqual(next(p), 11 * 8) self.assertRaises(StopIteration, next, p) def testFindAllCount(self): s = BitStream('0b1') * 100 for i in [0, 1, 23]: self.assertEqual(len(list(s.findall('0b1', count=i))), i) b = s.findall('0b1', bytealigned=True, count=-1) self.assertRaises(ValueError, next, b) def testContains(self): a = BitStream('0b1') + '0x0001dead0001' self.assertTrue('0xdead' in a) self.assertEqual(a.pos, 0) self.assertFalse('0xfeed' in a) def testRepr(self): max = bitstring.MAX_CHARS bls = ['', '0b1', '0o5', '0x43412424f41', '0b00101001010101'] for bs in bls: a = BitStream(bs) b = eval(a.__repr__()) self.assertTrue(a == b) for f in [ConstBitStream(filename='test.m1v'), ConstBitStream(filename='test.m1v', length=17), ConstBitStream(filename='test.m1v', length=23, offset=23102)]: f2 = eval(f.__repr__()) self.assertEqual(f._datastore._rawarray.source.name, f2._datastore._rawarray.source.name) self.assertTrue(f2.tobytes() == f.tobytes()) a = BitStream('0b1') self.assertEqual(repr(a), "BitStream('0b1')") a += '0b11' self.assertEqual(repr(a), "BitStream('0b111')") a += '0b1' self.assertEqual(repr(a), "BitStream('0xf')") a *= max self.assertEqual(repr(a), "BitStream('0x" + "f" * max + "')") a += '0xf' self.assertEqual(repr(a), "BitStream('0x" + "f" * max + "...') # length=%d" % (max * 4 + 4)) def testPrint(self): s = BitStream(hex='0x00') self.assertEqual('0x' + s.hex, s.__str__()) s = BitStream(filename='test.m1v') self.assertEqual('0x' + s[0:bitstring.MAX_CHARS * 4].hex + '...', s.__str__()) self.assertEqual(BitStream().__str__(), '') s = BitStream('0b11010') self.assertEqual('0b' + s.bin, s.__str__()) s = BitStream('0x12345678901234567890,0b1') self.assertEqual('0x12345678901234567890, 0b1', s.__str__()) def testIter(self): a = BitStream('0b001010') b = BitStream() for bit in a: b.append(ConstBitStream(bool=bit)) self.assertEqual(a, b) def testDelitem(self): a = BitStream('0xffee') del a[0:8] self.assertEqual(a.hex, 'ee') del a[0:8] self.assertFalse(a) del a[10:12] self.assertFalse(a) def testNonZeroBitsAtStart(self): a = BitStream(bytes=b'\xff', offset=2) b = BitStream('0b00') b += a self.assertTrue(b == '0b0011 1111') #self.assertEqual(a._datastore.rawbytes, b'\xff') self.assertEqual(a.tobytes(), b'\xfc') def testNonZeroBitsAtEnd(self): a = BitStream(bytes=b'\xff', length=5) #self.assertEqual(a._datastore.rawbytes, b'\xff') b = BitStream('0b00') a += b self.assertTrue(a == '0b1111100') self.assertEqual(a.tobytes(), b'\xf8') self.assertRaises(ValueError, a._getbytes) def testNewOffsetErrors(self): self.assertRaises(bitstring.CreationError, BitStream, hex='ff', offset=-1) self.assertRaises(bitstring.CreationError, BitStream, '0xffffffff', offset=33) def testSliceStep(self): a = BitStream('0x3') b = a[::1] self.assertEqual(a, b) self.assertEqual(a[2:4:1], '0b11') self.assertEqual(a[0:2:1], '0b00') self.assertEqual(a[:3], '0o1') a = BitStream('0x0011223344556677') self.assertEqual(a[-8:], '0x77') self.assertEqual(a[:-24], '0x0011223344') self.assertEqual(a[-1000:-24], '0x0011223344') def testInterestingSliceStep(self): a = BitStream('0b0011000111') self.assertEqual(a[7:3:-1], '0b1000') self.assertEqual(a[9:2:-1], '0b1110001') self.assertEqual(a[8:2:-2], '0b100') self.assertEqual(a[100:-20:-3], '0b1010') self.assertEqual(a[100:-20:-1], '0b1110001100') self.assertEqual(a[10:2:-1], '0b1110001') self.assertEqual(a[100:2:-1], '0b1110001') def testInsertionOrderAndBitpos(self): b = BitStream() b[0:0] = '0b0' b[0:0] = '0b1' self.assertEqual(b, '0b10') self.assertEqual(b.bitpos, 1) a = BitStream() a.insert('0b0') a.insert('0b1') self.assertEqual(a, '0b01') self.assertEqual(a.bitpos, 2) def testOverwriteOrderAndBitpos(self): a = BitStream('0xff') a.overwrite('0xa') self.assertEqual(a, '0xaf') self.assertEqual(a.bitpos, 4) a.overwrite('0xb') self.assertEqual(a, '0xab') self.assertEqual(a.bitpos, 8) self.assertRaises(ValueError, a.overwrite, '0b1') a.overwrite('0xa', 4) self.assertEqual(a, '0xaa') self.assertEqual(a.bitpos, 8) a.overwrite(a, 0) self.assertEqual(a, '0xaa') def testInitSliceWithInt(self): a = BitStream(length=8) a[:] = 100 self.assertEqual(a.uint, 100) a[0] = 1 self.assertEqual(a.bin, '11100100') a[1] = 0 self.assertEqual(a.bin, '10100100') a[-1] = -1 self.assertEqual(a.bin, '10100101') a[-3:] = -2 self.assertEqual(a.bin, '10100110') def testInitSliceWithIntErrors(self): a = BitStream('0b0000') self.assertRaises(ValueError, a.__setitem__, slice(0, 4), 16) self.assertRaises(ValueError, a.__setitem__, slice(0, 4), -9) self.assertRaises(ValueError, a.__setitem__, 0, 2) self.assertRaises(ValueError, a.__setitem__, 0, -2) def testReverseWithSlice(self): a = BitStream('0x0012ff') a.reverse() self.assertEqual(a, '0xff4800') a.reverse(8, 16) self.assertEqual(a, '0xff1200') b = a[8:16] b.reverse() a[8:16] = b self.assertEqual(a, '0xff4800') def testReverseWithSliceErrors(self): a = BitStream('0x123') self.assertRaises(ValueError, a.reverse, -1, 4) self.assertRaises(ValueError, a.reverse, 10, 9) self.assertRaises(ValueError, a.reverse, 1, 10000) def testInitialiseFromList(self): a = BitStream([]) self.assertFalse(a) a = BitStream([True, False, [], [0], 'hello']) self.assertEqual(a, '0b10011') a += [] self.assertEqual(a, '0b10011') a += [True, False, True] self.assertEqual(a, '0b10011101') a.find([12, 23]) self.assertEqual(a.pos, 3) self.assertEqual([1, 0, False, True], BitStream('0b1001')) a = [True] + BitStream('0b1') self.assertEqual(a, '0b11') def testInitialiseFromTuple(self): a = BitStream(()) self.assertFalse(a) a = BitStream((0, 1, '0', '1')) self.assertEqual('0b0111', a) a.replace((True, True), []) self.assertEqual(a, (False, True)) def testCut(self): a = BitStream('0x00112233445') b = list(a.cut(8)) self.assertEqual(b, ['0x00', '0x11', '0x22', '0x33', '0x44']) b = list(a.cut(4, 8, 16)) self.assertEqual(b, ['0x1', '0x1']) b = list(a.cut(4, 0, 44, 4)) self.assertEqual(b, ['0x0', '0x0', '0x1', '0x1']) a = BitStream() b = list(a.cut(10)) self.assertTrue(not b) def testCutErrors(self): a = BitStream('0b1') b = a.cut(1, 1, 2) self.assertRaises(ValueError, next, b) b = a.cut(1, -2, 1) self.assertRaises(ValueError, next, b) b = a.cut(0) self.assertRaises(ValueError, next, b) b = a.cut(1, count=-1) self.assertRaises(ValueError, next, b) def testCutProblem(self): s = BitStream('0x1234') for n in list(s.cut(4)): s.prepend(n) self.assertEqual(s, '0x43211234') def testJoinFunctions(self): a = BitStream().join(['0xa', '0xb', '0b1111']) self.assertEqual(a, '0xabf') a = BitStream('0b1').join(['0b0' for i in range(10)]) self.assertEqual(a, '0b0101010101010101010') a = BitStream('0xff').join([]) self.assertFalse(a) def testAddingBitpos(self): a = BitStream('0xff') b = BitStream('0x00') a.bitpos = b.bitpos = 8 c = a + b self.assertEqual(c.bitpos, 0) def testIntelligentRead1(self): a = BitStream(uint=123, length=23) u = a.read('uint:23') self.assertEqual(u, 123) self.assertEqual(a.pos, a.len) b = BitStream(int=-12, length=44) i = b.read('int:44') self.assertEqual(i, -12) self.assertEqual(b.pos, b.len) u2, i2 = (a + b).readlist('uint:23, int:44') self.assertEqual((u2, i2), (123, -12)) def testIntelligentRead2(self): a = BitStream(ue=822) u = a.read('ue') self.assertEqual(u, 822) self.assertEqual(a.pos, a.len) b = BitStream(se=-1001) s = b.read('se') self.assertEqual(s, -1001) self.assertEqual(b.pos, b.len) s, u1, u2 = (b + 2 * a).readlist('se, ue, ue') self.assertEqual((s, u1, u2), (-1001, 822, 822)) def testIntelligentRead3(self): a = BitStream('0x123') + '0b11101' h = a.read('hex:12') self.assertEqual(h, '123') b = a.read('bin: 5') self.assertEqual(b, '11101') c = '0b' + b + a b, h = c.readlist('bin:5, hex:12') self.assertEqual((b, h), ('11101', '123')) def testIntelligentRead4(self): a = BitStream('0o007') o = a.read('oct:9') self.assertEqual(o, '007') self.assertEqual(a.pos, a.len) def testIntelligentRead5(self): a = BitStream('0x00112233') c0, c1, c2 = a.readlist('bits:8, bits:8, bits:16') self.assertEqual((c0, c1, c2), (BitStream('0x00'), BitStream('0x11'), BitStream('0x2233'))) a.pos = 0 c = a.read('bits:16') self.assertEqual(c, BitStream('0x0011')) def testIntelligentRead6(self): a = BitStream('0b000111000') b1, b2, b3 = a.readlist('bin :3, int: 3, int:3') self.assertEqual(b1, '000') self.assertEqual(b2, -1) self.assertEqual(b3, 0) def testIntelligentRead7(self): a = BitStream('0x1234') a1, a2, a3, a4 = a.readlist('bin:0, oct:0, hex:0, bits:0') self.assertTrue(a1 == a2 == a3 == '') self.assertFalse(a4) self.assertRaises(ValueError, a.read, 'int:0') self.assertRaises(ValueError, a.read, 'uint:0') self.assertEqual(a.pos, 0) def testIntelligentRead8(self): a = BitStream('0x123456') for t in ['hex:1', 'oct:1', 'hex4', '-5', 'fred', 'bin:-2', 'uint:p', 'uint:-2', 'int:u', 'int:-3', 'ses', 'uee', '-14']: self.assertRaises(ValueError, a.read, t) def testIntelligentRead9(self): a = BitStream('0xff') self.assertEqual(a.read('intle'), -1) def testFillerReads1(self): s = BitStream('0x012345') t = s.read('bits') self.assertEqual(s, t) s.pos = 0 a, b = s.readlist('hex:8, hex') self.assertEqual(a, '01') self.assertEqual(b, '2345') self.assertTrue(isinstance(b, str)) s.bytepos = 0 a, b = s.readlist('bin, hex:20') self.assertEqual(a, '0000') self.assertEqual(b, '12345') self.assertTrue(isinstance(a, str)) def testFillerReads2(self): s = BitStream('0xabcdef') self.assertRaises(bitstring.Error, s.readlist, 'bits, se') self.assertRaises(bitstring.Error, s.readlist, 'hex:4, bits, ue, bin:4') s.pos = 0 self.assertRaises(bitstring.Error, s.readlist, 'bin, bin') def testIntelligentPeek(self): a = BitStream('0b01, 0x43, 0o4, uint:23=2, se=5, ue=3') b, c, e = a.peeklist('bin:2, hex:8, oct:3') self.assertEqual((b, c, e), ('01', '43', '4')) self.assertEqual(a.pos, 0) a.pos = 13 f, g, h = a.peeklist('uint:23, se, ue') self.assertEqual((f, g, h), (2, 5, 3)) self.assertEqual(a.pos, 13) def testReadMultipleBits(self): s = BitStream('0x123456789abcdef') a, b = s.readlist([4, 4]) self.assertEqual(a, '0x1') self.assertEqual(b, '0x2') c, d, e = s.readlist([8, 16, 8]) self.assertEqual(c, '0x34') self.assertEqual(d, '0x5678') self.assertEqual(e, '0x9a') def testPeekMultipleBits(self): s = BitStream('0b1101, 0o721, 0x2234567') a, b, c, d = s.peeklist([2, 1, 1, 9]) self.assertEqual(a, '0b11') self.assertEqual(bool(b), False) self.assertEqual(bool(c), True) self.assertEqual(d, '0o721') self.assertEqual(s.pos, 0) a, b = s.peeklist([4, 9]) self.assertEqual(a, '0b1101') self.assertEqual(b, '0o721') s.pos = 13 a, b = s.peeklist([16, 8]) self.assertEqual(a, '0x2234') self.assertEqual(b, '0x56') self.assertEqual(s.pos, 13) def testDifficultPrepends(self): a = BitStream('0b1101011') b = BitStream() for i in range(10): b.prepend(a) self.assertEqual(b, a * 10) def testPackingWrongNumberOfThings(self): self.assertRaises(bitstring.CreationError, pack, 'bin:1') self.assertRaises(bitstring.CreationError, pack, '', 100) def testPackWithVariousKeys(self): a = pack('uint10', uint10='0b1') self.assertEqual(a, '0b1') b = pack('0b110', **{'0b110': '0xfff'}) self.assertEqual(b, '0xfff') def testPackWithVariableLength(self): for i in range(1, 11): a = pack('uint:n', 0, n=i) self.assertEqual(a.bin, '0' * i) def testToBytes(self): a = BitStream(bytes=b'\xab\x00') b = a.tobytes() self.assertEqual(a.bytes, b) for i in range(7): del a[-1:] self.assertEqual(a.tobytes(), b'\xab\x00') del a[-1:] self.assertEqual(a.tobytes(), b'\xab') def testToFile(self): a = BitStream('0x0000ff')[:17] f = open('temp_bitstring_unit_testing_file', 'wb') a.tofile(f) f.close() b = BitStream(filename='temp_bitstring_unit_testing_file') self.assertEqual(b, '0x000080') a = BitStream('0x911111') del a[:1] self.assertEqual(a + '0b0', '0x222222') f = open('temp_bitstring_unit_testing_file', 'wb') a.tofile(f) f.close() b = BitStream(filename='temp_bitstring_unit_testing_file') self.assertEqual(b, '0x222222') os.remove('temp_bitstring_unit_testing_file') #def testToFileWithLargerFile(self): # a = BitStream(length=16000000) # a[1] = '0b1' # a[-2] = '0b1' # f = open('temp_bitstring_unit_testing_file' ,'wb') # a.tofile(f) # f.close() # b = BitStream(filename='temp_bitstring_unit_testing_file') # self.assertEqual(b.len, 16000000) # self.assertEqual(b[1], True) # # f = open('temp_bitstring_unit_testing_file' ,'wb') # a[1:].tofile(f) # f.close() # b = BitStream(filename='temp_bitstring_unit_testing_file') # self.assertEqual(b.len, 16000000) # self.assertEqual(b[0], True) # os.remove('temp_bitstring_unit_testing_file') def testTokenParser(self): tp = bitstring.tokenparser self.assertEqual(tp('hex'), (True, [('hex', None, None)])) self.assertEqual(tp('hex=14'), (True, [('hex', None, '14')])) self.assertEqual(tp('se'), (False, [('se', None, None)])) self.assertEqual(tp('ue=12'), (False, [('ue', None, '12')])) self.assertEqual(tp('0xef'), (False, [('0x', None, 'ef')])) self.assertEqual(tp('uint:12'), (False, [('uint', 12, None)])) self.assertEqual(tp('int:30=-1'), (False, [('int', 30, '-1')])) self.assertEqual(tp('bits:10'), (False, [('bits', 10, None)])) self.assertEqual(tp('bits:10'), (False, [('bits', 10, None)])) self.assertEqual(tp('123'), (False, [('uint', 123, None)])) self.assertEqual(tp('123'), (False, [('uint', 123, None)])) self.assertRaises(ValueError, tp, 'hex12') self.assertEqual(tp('hex12', ('hex12',)), (False, [('hex12', None, None)])) self.assertEqual(tp('2*bits:6'), (False, [('bits', 6, None), ('bits', 6, None)])) def testAutoFromFileObject(self): with open('test.m1v', 'rb') as f: s = ConstBitStream(f, offset=32, length=12) self.assertEqual(s.uint, 352) t = ConstBitStream('0xf') + f self.assertTrue(t.startswith('0xf000001b3160')) s2 = ConstBitStream(f) t2 = BitStream('0xc') t2.prepend(s2) self.assertTrue(t2.startswith('0x000001b3')) self.assertTrue(t2.endswith('0xc')) with open('test.m1v', 'rb') as b: u = BitStream(bytes=b.read()) # TODO: u == s2 is much slower than u.bytes == s2.bytes self.assertEqual(u.bytes, s2.bytes) def testFileBasedCopy(self): with open('smalltestfile', 'rb') as f: s = BitStream(f) t = BitStream(s) s.prepend('0b1') self.assertEqual(s[1:], t) s = BitStream(f) t = copy.copy(s) t.append('0b1') self.assertEqual(s, t[:-1]) def testBigEndianSynonyms(self): s = BitStream('0x12318276ef') self.assertEqual(s.int, s.intbe) self.assertEqual(s.uint, s.uintbe) s = BitStream(intbe=-100, length=16) self.assertEqual(s, 'int:16=-100') s = BitStream(uintbe=13, length=24) self.assertEqual(s, 'int:24=13') s = BitStream('uintbe:32=1000') self.assertEqual(s, 'uint:32=1000') s = BitStream('intbe:8=2') self.assertEqual(s, 'int:8=2') self.assertEqual(s.read('intbe'), 2) s.pos = 0 self.assertEqual(s.read('uintbe'), 2) def testBigEndianSynonymErrors(self): self.assertRaises(bitstring.CreationError, BitStream, uintbe=100, length=15) self.assertRaises(bitstring.CreationError, BitStream, intbe=100, length=15) self.assertRaises(bitstring.CreationError, BitStream, 'uintbe:17=100') self.assertRaises(bitstring.CreationError, BitStream, 'intbe:7=2') s = BitStream('0b1') self.assertRaises(bitstring.InterpretError, s._getintbe) self.assertRaises(bitstring.InterpretError, s._getuintbe) self.assertRaises(ValueError, s.read, 'uintbe') self.assertRaises(ValueError, s.read, 'intbe') def testLittleEndianUint(self): s = BitStream(uint=100, length=16) self.assertEqual(s.uintle, 25600) s = BitStream(uintle=100, length=16) self.assertEqual(s.uint, 25600) self.assertEqual(s.uintle, 100) s.uintle += 5 self.assertEqual(s.uintle, 105) s = BitStream('uintle:32=999') self.assertEqual(s.uintle, 999) s.byteswap() self.assertEqual(s.uint, 999) s = pack('uintle:24', 1001) self.assertEqual(s.uintle, 1001) self.assertEqual(s.length, 24) self.assertEqual(s.read('uintle'), 1001) def testLittleEndianInt(self): s = BitStream(int=100, length=16) self.assertEqual(s.intle, 25600) s = BitStream(intle=100, length=16) self.assertEqual(s.int, 25600) self.assertEqual(s.intle, 100) s.intle += 5 self.assertEqual(s.intle, 105) s = BitStream('intle:32=999') self.assertEqual(s.intle, 999) s.byteswap() self.assertEqual(s.int, 999) s = pack('intle:24', 1001) self.assertEqual(s.intle, 1001) self.assertEqual(s.length, 24) self.assertEqual(s.read('intle'), 1001) def testLittleEndianErrors(self): self.assertRaises(bitstring.CreationError, BitStream, 'uintle:15=10') self.assertRaises(bitstring.CreationError, BitStream, 'intle:31=-999') self.assertRaises(bitstring.CreationError, BitStream, uintle=100, length=15) self.assertRaises(bitstring.CreationError, BitStream, intle=100, length=15) s = BitStream('0xfff') self.assertRaises(bitstring.InterpretError, s._getintle) self.assertRaises(bitstring.InterpretError, s._getuintle) self.assertRaises(ValueError, s.read, 'uintle') self.assertRaises(ValueError, s.read, 'intle') def testStructTokens1(self): self.assertEqual(pack('b', 23), BitStream('intbe:8=23')) self.assertEqual(pack('>B', 23), BitStream('uintbe:8=23')) self.assertEqual(pack('>h', 23), BitStream('intbe:16=23')) self.assertEqual(pack('>H', 23), BitStream('uintbe:16=23')) self.assertEqual(pack('>l', 23), BitStream('intbe:32=23')) self.assertEqual(pack('>L', 23), BitStream('uintbe:32=23')) self.assertEqual(pack('>q', 23), BitStream('intbe:64=23')) self.assertEqual(pack('>Q', 23), BitStream('uintbe:64=23')) self.assertRaises(bitstring.CreationError, pack, '2L', 40, 40)) def testStructTokens2(self): s = pack('>hhl', 1, 2, 3) a, b, c = s.unpack('>hhl') self.assertEqual((a, b, c), (1, 2, 3)) s = pack('Q \tL', 1001, 43, 21, 9999) self.assertEqual(s.unpack('QL'), [1001, 43, 21, 9999]) def testStructTokensMultiplicativeFactors(self): s = pack('<2h', 1, 2) a, b = s.unpack('<2h') self.assertEqual((a, b), (1, 2)) s = pack('<100q', *range(100)) self.assertEqual(s.len, 100 * 64) self.assertEqual(s[44*64:45*64].uintle, 44) s = pack('@L0B2h', 5, 5, 5) self.assertEqual(s.unpack('@Lhh'), [5, 5, 5]) def testStructTokensErrors(self): for f in ['>>q', '<>q', 'q>', '2q', 'q', '>-2q', '@a', '>int:8', '>q2']: self.assertRaises(bitstring.CreationError, pack, f, 100) def testImmutableBitStreams(self): a = ConstBitStream('0x012345') self.assertEqual(a, '0x012345') b = BitStream('0xf') + a self.assertEqual(b, '0xf012345') try: a.append(b) self.assertTrue(False) except AttributeError: pass try: a.prepend(b) self.assertTrue(False) except AttributeError: pass try: a[0] = '0b1' self.assertTrue(False) except TypeError: pass try: del a[5] self.assertTrue(False) except TypeError: pass try: a.replace('0b1', '0b0') self.assertTrue(False) except AttributeError: pass try: a.insert('0b11', 4) self.assertTrue(False) except AttributeError: pass try: a.reverse() self.assertTrue(False) except AttributeError: pass try: a.reversebytes() self.assertTrue(False) except AttributeError: pass self.assertEqual(a, '0x012345') self.assertTrue(isinstance(a, ConstBitStream)) def testReverseBytes(self): a = BitStream('0x123456') a.byteswap() self.assertEqual(a, '0x563412') b = a + '0b1' b.byteswap() self.assertEqual('0x123456, 0b1', b) a = BitStream('0x54') a.byteswap() self.assertEqual(a, '0x54') a = BitStream() a.byteswap() self.assertFalse(a) def testReverseBytes2(self): a = BitStream() a.byteswap() self.assertFalse(a) a = BitStream('0x00112233') a.byteswap(0, 0, 16) self.assertEqual(a, '0x11002233') a.byteswap(0, 4, 28) self.assertEqual(a, '0x12302103') a.byteswap(start=0, end=18) self.assertEqual(a, '0x30122103') self.assertRaises(ValueError, a.byteswap, 0, 10, 2) self.assertRaises(ValueError, a.byteswap, 0, -4, 4) self.assertRaises(ValueError, a.byteswap, 0, 24, 48) a.byteswap(0, 24) self.assertEqual(a, '0x30122103') a.byteswap(0, 11, 11) self.assertEqual(a, '0x30122103') def testCapitalsInPack(self): a = pack('A', A='0b1') self.assertEqual(a, '0b1') format = 'bits:4=BL_OFFT, uint:12=width, uint:12=height' d = {'BL_OFFT': '0b1011', 'width': 352, 'height': 288} s = bitstring.pack(format, **d) self.assertEqual(s, '0b1011, uint:12=352, uint:12=288') a = pack('0X0, uint:8, hex', 45, '0XABcD') self.assertEqual(a, '0x0, uint:8=45, 0xabCD') def testOtherCapitals(self): a = ConstBitStream('0XABC, 0O0, 0B11') self.assertEqual(a, 'hex=0Xabc, oct=0, bin=0B11') def testEfficientOverwrite(self): a = BitStream(1000000000) a.overwrite([1], 123456) self.assertEqual(a[123456], True) a.overwrite('0xff', 1) self.assertEqual(a[0:32:1], '0x7f800000') b = BitStream('0xffff') b.overwrite('0x0000') self.assertEqual(b, '0x0000') self.assertEqual(b.pos, 16) c = BitStream(length=1000) c.overwrite('0xaaaaaaaaaaaa', 81) self.assertEqual(c[81:81 + 6 * 8], '0xaaaaaaaaaaaa') self.assertEqual(len(list(c.findall('0b1'))), 24) s = BitStream(length=1000) s = s[5:] s.overwrite('0xffffff', 500) s.pos = 500 self.assertEqual(s.read(4 * 8), '0xffffff00') s.overwrite('0xff', 502) self.assertEqual(s[502:518], '0xffff') def testPeekAndReadListErrors(self): a = BitStream('0x123456') self.assertRaises(ValueError, a.read, 'hex:8, hex:8') self.assertRaises(ValueError, a.peek, 'hex:8, hex:8') self.assertRaises(TypeError, a.read, 10, 12) self.assertRaises(TypeError, a.peek, 12, 14) self.assertRaises(TypeError, a.read, 8, 8) self.assertRaises(TypeError, a.peek, 80, 80) def testStartswith(self): a = BitStream() self.assertTrue(a.startswith(BitStream())) self.assertFalse(a.startswith('0b0')) a = BitStream('0x12ff') self.assertTrue(a.startswith('0x1')) self.assertTrue(a.startswith('0b0001001')) self.assertTrue(a.startswith('0x12ff')) self.assertFalse(a.startswith('0x12ff, 0b1')) self.assertFalse(a.startswith('0x2')) def testStartswithStartEnd(self): s = BitStream('0x123456') self.assertTrue(s.startswith('0x234', 4)) self.assertFalse(s.startswith('0x123', end=11)) self.assertTrue(s.startswith('0x123', end=12)) self.assertTrue(s.startswith('0x34', 8, 16)) self.assertFalse(s.startswith('0x34', 7, 16)) self.assertFalse(s.startswith('0x34', 9, 16)) self.assertFalse(s.startswith('0x34', 8, 15)) def testEndswith(self): a = BitStream() self.assertTrue(a.endswith('')) self.assertFalse(a.endswith(BitStream('0b1'))) a = BitStream('0xf2341') self.assertTrue(a.endswith('0x41')) self.assertTrue(a.endswith('0b001')) self.assertTrue(a.endswith('0xf2341')) self.assertFalse(a.endswith('0x1f2341')) self.assertFalse(a.endswith('0o34')) def testEndswithStartEnd(self): s = BitStream('0x123456') self.assertTrue(s.endswith('0x234', end=16)) self.assertFalse(s.endswith('0x456', start=13)) self.assertTrue(s.endswith('0x456', start=12)) self.assertTrue(s.endswith('0x34', 8, 16)) self.assertTrue(s.endswith('0x34', 7, 16)) self.assertFalse(s.endswith('0x34', 9, 16)) self.assertFalse(s.endswith('0x34', 8, 15)) def testUnhashability(self): s = BitStream('0xf') self.assertRaises(TypeError, set, [s]) self.assertRaises(TypeError, hash, [s]) def testConstBitStreamSetCreation(self): sl = [ConstBitStream(uint=i, length=7) for i in range(15)] s = set(sl) self.assertEqual(len(s), 15) s.add(ConstBitStream('0b0000011')) self.assertEqual(len(s), 15) self.assertRaises(TypeError, s.add, BitStream('0b0000011')) def testConstBitStreamFunctions(self): s = ConstBitStream('0xf, 0b1') self.assertEqual(type(s), ConstBitStream) t = copy.copy(s) self.assertEqual(type(t), ConstBitStream) a = s + '0o3' self.assertEqual(type(a), ConstBitStream) b = a[0:4] self.assertEqual(type(b), ConstBitStream) b = a[4:3] self.assertEqual(type(b), ConstBitStream) b = a[5:2:-1] self.assertEqual(type(b), ConstBitStream) b = ~a self.assertEqual(type(b), ConstBitStream) b = a << 2 self.assertEqual(type(b), ConstBitStream) b = a >> 2 self.assertEqual(type(b), ConstBitStream) b = a * 2 self.assertEqual(type(b), ConstBitStream) b = a * 0 self.assertEqual(type(b), ConstBitStream) b = a & ~a self.assertEqual(type(b), ConstBitStream) b = a | ~a self.assertEqual(type(b), ConstBitStream) b = a ^ ~a self.assertEqual(type(b), ConstBitStream) b = a._slice(4, 4) self.assertEqual(type(b), ConstBitStream) b = a.read(4) self.assertEqual(type(b), ConstBitStream) def testConstBitStreamProperties(self): a = ConstBitStream('0x123123') try: a.hex = '0x234' self.assertTrue(False) except AttributeError: pass try: a.oct = '0o234' self.assertTrue(False) except AttributeError: pass try: a.bin = '0b101' self.assertTrue(False) except AttributeError: pass try: a.ue = 3453 self.assertTrue(False) except AttributeError: pass try: a.se = -123 self.assertTrue(False) except AttributeError: pass try: a.int = 432 self.assertTrue(False) except AttributeError: pass try: a.uint = 4412 self.assertTrue(False) except AttributeError: pass try: a.intle = 123 self.assertTrue(False) except AttributeError: pass try: a.uintle = 4412 self.assertTrue(False) except AttributeError: pass try: a.intbe = 123 self.assertTrue(False) except AttributeError: pass try: a.uintbe = 4412 self.assertTrue(False) except AttributeError: pass try: a.intne = 123 self.assertTrue(False) except AttributeError: pass try: a.uintne = 4412 self.assertTrue(False) except AttributeError: pass try: a.bytes = b'hello' self.assertTrue(False) except AttributeError: pass def testConstBitStreamMisc(self): a = ConstBitStream('0xf') b = a a += '0xe' self.assertEqual(b, '0xf') self.assertEqual(a, '0xfe') c = BitStream(a) self.assertEqual(a, c) a = ConstBitStream('0b1') a._append(a) self.assertEqual(a, '0b11') self.assertEqual(type(a), ConstBitStream) a._prepend(a) self.assertEqual(a, '0b1111') self.assertEqual(type(a), ConstBitStream) def testConstBitStreamHashibility(self): a = ConstBitStream('0x1') b = ConstBitStream('0x2') c = ConstBitStream('0x1') c.pos = 3 s = set((a, b, c)) self.assertEqual(len(s), 2) self.assertEqual(hash(a), hash(c)) def testConstBitStreamCopy(self): a = ConstBitStream('0xabc') a.pos = 11 b = copy.copy(a) b.pos = 4 self.assertEqual(id(a._datastore), id(b._datastore)) self.assertEqual(a.pos, 11) self.assertEqual(b.pos, 4) def testPython26stuff(self): s = BitStream('0xff') self.assertTrue(isinstance(s.tobytes(), bytes)) self.assertTrue(isinstance(s.bytes, bytes)) def testReadFromBits(self): a = ConstBitStream('0xaabbccdd') b = a.read(8) self.assertEqual(b, '0xaa') self.assertEqual(a[0:8], '0xaa') self.assertEqual(a[-1], True) a.pos = 0 self.assertEqual(a.read(4).uint, 10) class Set(unittest.TestCase): def testSet(self): a = BitStream(length=16) a.set(True, 0) self.assertEqual(a, '0b10000000 00000000') a.set(1, 15) self.assertEqual(a, '0b10000000 00000001') b = a[4:12] b.set(True, 1) self.assertEqual(b, '0b01000000') b.set(True, -1) self.assertEqual(b, '0b01000001') b.set(1, -8) self.assertEqual(b, '0b11000001') self.assertRaises(IndexError, b.set, True, -9) self.assertRaises(IndexError, b.set, True, 8) def testSetNegativeIndex(self): a = BitStream(10) a.set(1, -1) self.assertEqual(a.bin, '0000000001') a.set(1, [-1, -10]) self.assertEqual(a.bin, '1000000001') self.assertRaises(IndexError, a.set, 1, [-11]) def testFileBasedSetUnset(self): a = BitStream(filename='test.m1v') a.set(True, (0, 1, 2, 3, 4)) self.assertEqual(a[0:32], '0xf80001b3') a = BitStream(filename='test.m1v') a.set(False, (28, 29, 30, 31)) self.assertTrue(a.startswith('0x000001b0')) def testSetList(self): a = BitStream(length=18) a.set(True, range(18)) self.assertEqual(a.int, -1) a.set(False, range(18)) self.assertEqual(a.int, 0) def testUnset(self): a = BitStream(length=16, int=-1) a.set(False, 0) self.assertEqual(~a, '0b10000000 00000000') a.set(0, 15) self.assertEqual(~a, '0b10000000 00000001') b = a[4:12] b.set(False, 1) self.assertEqual(~b, '0b01000000') b.set(False, -1) self.assertEqual(~b, '0b01000001') b.set(False, -8) self.assertEqual(~b, '0b11000001') self.assertRaises(IndexError, b.set, False, -9) self.assertRaises(IndexError, b.set, False, 8) def testSetWholeBitStream(self): a = BitStream(14) a.set(1) self.assertTrue(a.all(1)) a.set(0) self.assertTrue(a.all(0)) class Invert(unittest.TestCase): def testInvertBits(self): a = BitStream('0b111000') a.invert(range(a.len)) self.assertEqual(a, '0b000111') a.invert([0, 1, -1]) self.assertEqual(a, '0b110110') def testInvertWholeBitStream(self): a = BitStream('0b11011') a.invert() self.assertEqual(a, '0b00100') def testInvertSingleBit(self): a = BitStream('0b000001') a.invert(0) self.assertEqual(a.bin, '100001') a.invert(-1) self.assertEqual(a.bin, '100000') def testInvertErrors(self): a = BitStream(10) self.assertRaises(IndexError, a.invert, 10) self.assertRaises(IndexError, a.invert, -11) self.assertRaises(IndexError, a.invert, [1, 2, 10]) ####################### def testIor(self): a = BitStream('0b1101001') a |= '0b1110000' self.assertEqual(a, '0b1111001') b = a[2:] c = a[1:-1] b |= c self.assertEqual(c, '0b11100') self.assertEqual(b, '0b11101') def testIand(self): a = BitStream('0b0101010101000') a &= '0b1111110000000' self.assertEqual(a, '0b0101010000000') s = BitStream(filename='test.m1v', offset=26, length=24) s &= '0xff00ff' self.assertEqual(s, '0xcc0004') def testIxor(self): a = BitStream('0b11001100110011') a ^= '0b11111100000010' self.assertEqual(a, '0b00110000110001') def testLogicalInplaceErrors(self): a = BitStream(4) self.assertRaises(ValueError, a.__ior__, '0b111') self.assertRaises(ValueError, a.__iand__, '0b111') self.assertRaises(ValueError, a.__ixor__, '0b111') class AllAndAny(unittest.TestCase): def testAll(self): a = BitStream('0b0111') self.assertTrue(a.all(True, (1, 3))) self.assertFalse(a.all(True, (0, 1, 2))) self.assertTrue(a.all(True, [-1])) self.assertFalse(a.all(True, [0])) def testFileBasedAll(self): a = BitStream(filename='test.m1v') self.assertTrue(a.all(True, [31])) a = BitStream(filename='test.m1v') self.assertTrue(a.all(False, (0, 1, 2, 3, 4))) def testFileBasedAny(self): a = BitStream(filename='test.m1v') self.assertTrue(a.any(True, (31, 12))) a = BitStream(filename='test.m1v') self.assertTrue(a.any(False, (0, 1, 2, 3, 4))) def testAny(self): a = BitStream('0b10011011') self.assertTrue(a.any(True, (1, 2, 3, 5))) self.assertFalse(a.any(True, (1, 2, 5))) self.assertTrue(a.any(True, (-1,))) self.assertFalse(a.any(True, (1,))) def testAllFalse(self): a = BitStream('0b0010011101') self.assertTrue(a.all(False, (0, 1, 3, 4))) self.assertFalse(a.all(False, (0, 1, 2, 3, 4))) def testAnyFalse(self): a = BitStream('0b01001110110111111111111111111') self.assertTrue(a.any(False, (4, 5, 6, 2))) self.assertFalse(a.any(False, (1, 15, 20))) def testAnyEmptyBitstring(self): a = ConstBitStream() self.assertFalse(a.any(True)) self.assertFalse(a.any(False)) def testAllEmptyBitStream(self): a = ConstBitStream() self.assertTrue(a.all(True)) self.assertTrue(a.all(False)) def testAnyWholeBitstring(self): a = ConstBitStream('0xfff') self.assertTrue(a.any(True)) self.assertFalse(a.any(False)) def testAllWholeBitstring(self): a = ConstBitStream('0xfff') self.assertTrue(a.all(True)) self.assertFalse(a.all(False)) def testErrors(self): a = BitStream('0xf') self.assertRaises(IndexError, a.all, True, [5]) self.assertRaises(IndexError, a.all, True, [-5]) self.assertRaises(IndexError, a.any, True, [5]) self.assertRaises(IndexError, a.any, True, [-5]) ################### def testFloatInitialisation(self): for f in (0.0000001, -1.0, 1.0, 0.2, -3.1415265, 1.331e32): a = BitStream(float=f, length=64) a.pos = 6 self.assertEqual(a.float, f) a = BitStream('float:64=%s' % str(f)) a.pos = 6 self.assertEqual(a.float, f) a = BitStream('floatbe:64=%s' % str(f)) a.pos = 6 self.assertEqual(a.floatbe, f) a = BitStream('floatle:64=%s' % str(f)) a.pos = 6 self.assertEqual(a.floatle, f) a = BitStream('floatne:64=%s' % str(f)) a.pos = 6 self.assertEqual(a.floatne, f) b = BitStream(float=f, length=32) b.pos = 6 self.assertAlmostEqual(b.float / f, 1.0) b = BitStream('float:32=%s' % str(f)) b.pos = 6 self.assertAlmostEqual(b.float / f, 1.0) b = BitStream('floatbe:32=%s' % str(f)) b.pos = 6 self.assertAlmostEqual(b.floatbe / f, 1.0) b = BitStream('floatle:32=%s' % str(f)) b.pos = 6 self.assertAlmostEqual(b.floatle / f, 1.0) b = BitStream('floatne:32=%s' % str(f)) b.pos = 6 self.assertAlmostEqual(b.floatne / f, 1.0) a = BitStream('0x12345678') a.pos = 6 a.float = 23 self.assertEqual(a.float, 23.0) def testFloatInitStrings(self): for s in ('5', '+0.0001', '-1e101', '4.', '.2', '-.65', '43.21E+32'): a = BitStream('float:64=%s' % s) self.assertEqual(a.float, float(s)) def testFloatPacking(self): a = pack('>d', 0.01) self.assertEqual(a.float, 0.01) self.assertEqual(a.floatbe, 0.01) a.byteswap() self.assertEqual(a.floatle, 0.01) b = pack('>f', 1e10) self.assertAlmostEqual(b.float / 1e10, 1.0) c = pack('5d', 10.0, 5.0, 2.5, 1.25, 0.1) self.assertEqual(d.unpack('>5d'), [10.0, 5.0, 2.5, 1.25, 0.1]) def testFloatReading(self): a = BitStream('floatle:64=12, floatbe:64=-0.01, floatne:64=3e33') x, y, z = a.readlist('floatle:64, floatbe:64, floatne:64') self.assertEqual(x, 12.0) self.assertEqual(y, -0.01) self.assertEqual(z, 3e33) a = BitStream('floatle:32=12, floatbe:32=-0.01, floatne:32=3e33') x, y, z = a.readlist('floatle:32, floatbe:32, floatne:32') self.assertAlmostEqual(x / 12.0, 1.0) self.assertAlmostEqual(y / -0.01, 1.0) self.assertAlmostEqual(z / 3e33, 1.0) a = BitStream('0b11, floatle:64=12, 0xfffff') a.pos = 2 self.assertEqual(a.read('floatle:64'), 12.0) b = BitStream(floatle=20, length=32) b.floatle = 10.0 b = [0] + b self.assertEqual(b[1:].floatle, 10.0) def testNonAlignedFloatReading(self): s = BitStream('0b1, float:32 = 10.0') x, y = s.readlist('1, float:32') self.assertEqual(y, 10.0) s[1:] = 'floatle:32=20.0' x, y = s.unpack('1, floatle:32') self.assertEqual(y, 20.0) def testFloatErrors(self): a = BitStream('0x3') self.assertRaises(bitstring.InterpretError, a._getfloat) self.assertRaises(bitstring.CreationError, a._setfloat, -0.2) for l in (8, 10, 12, 16, 30, 128, 200): self.assertRaises(ValueError, BitStream, float=1.0, length=l) self.assertRaises(bitstring.CreationError, BitStream, floatle=0.3, length=0) self.assertRaises(bitstring.CreationError, BitStream, floatle=0.3, length=1) self.assertRaises(bitstring.CreationError, BitStream, float=2) self.assertRaises(bitstring.InterpretError, a.read, 'floatle:2') def testReadErrorChangesPos(self): a = BitStream('0x123123') try: a.read('10, 5') except ValueError: pass self.assertEqual(a.pos, 0) def testRor(self): a = BitStream('0b11001') a.ror(0) self.assertEqual(a, '0b11001') a.ror(1) self.assertEqual(a, '0b11100') a.ror(5) self.assertEqual(a, '0b11100') a.ror(101) self.assertEqual(a, '0b01110') a = BitStream('0b1') a.ror(1000000) self.assertEqual(a, '0b1') def testRorErrors(self): a = BitStream() self.assertRaises(bitstring.Error, a.ror, 0) a += '0b001' self.assertRaises(ValueError, a.ror, -1) def testRol(self): a = BitStream('0b11001') a.rol(0) self.assertEqual(a, '0b11001') a.rol(1) self.assertEqual(a, '0b10011') a.rol(5) self.assertEqual(a, '0b10011') a.rol(101) self.assertEqual(a, '0b00111') a = BitStream('0b1') a.rol(1000000) self.assertEqual(a, '0b1') def testRolFromFile(self): a = BitStream(filename='test.m1v') l = a.len a.rol(1) self.assertTrue(a.startswith('0x000003')) self.assertEqual(a.len, l) self.assertTrue(a.endswith('0x0036e')) def testRorFromFile(self): a = BitStream(filename='test.m1v') l = a.len a.ror(1) self.assertTrue(a.startswith('0x800000')) self.assertEqual(a.len, l) self.assertTrue(a.endswith('0x000db')) def testRolErrors(self): a = BitStream() self.assertRaises(bitstring.Error, a.rol, 0) a += '0b001' self.assertRaises(ValueError, a.rol, -1) def testBytesToken(self): a = BitStream('0x010203') b = a.read('bytes:1') self.assertTrue(isinstance(b, bytes)) self.assertEqual(b, b'\x01') x, y, z = a.unpack('4, bytes:2, uint') self.assertEqual(x, 0) self.assertEqual(y, b'\x10\x20') self.assertEqual(z, 3) s = pack('bytes:4', b'abcd') self.assertEqual(s.bytes, b'abcd') def testBytesTokenMoreThoroughly(self): a = BitStream('0x0123456789abcdef') a.pos += 16 self.assertEqual(a.read('bytes:1'), b'\x45') self.assertEqual(a.read('bytes:3'), b'\x67\x89\xab') x, y, z = a.unpack('bits:28, bytes, bits:12') self.assertEqual(y, b'\x78\x9a\xbc') def testDedicatedReadFunctions(self): a = BitStream('0b11, uint:43=98798798172, 0b11111') x = a._readuint(43, 2) self.assertEqual(x, 98798798172) self.assertEqual(a.pos, 0) x = a._readint(43, 2) self.assertEqual(x, 98798798172) self.assertEqual(a.pos, 0) a = BitStream('0b11, uintbe:48=98798798172, 0b11111') x = a._readuintbe(48, 2) self.assertEqual(x, 98798798172) self.assertEqual(a.pos, 0) x = a._readintbe(48, 2) self.assertEqual(x, 98798798172) self.assertEqual(a.pos, 0) a = BitStream('0b111, uintle:40=123516, 0b111') self.assertEqual(a._readuintle(40, 3), 123516) b = BitStream('0xff, uintle:800=999, 0xffff') self.assertEqual(b._readuintle(800, 8), 999) a = BitStream('0b111, intle:48=999999999, 0b111111111111') self.assertEqual(a._readintle(48, 3), 999999999) b = BitStream('0xff, intle:200=918019283740918263512351235, 0xfffffff') self.assertEqual(b._readintle(200, 8), 918019283740918263512351235) a = BitStream('0b111, floatbe:64=-5.32, 0xffffffff') self.assertEqual(a._readfloat(64, 3), -5.32) a = BitStream('0b111, floatle:64=9.9998, 0b111') self.assertEqual(a._readfloatle(64, 3), 9.9998) def testAutoInitWithInt(self): a = BitStream(0) self.assertFalse(a) a = BitStream(1) self.assertEqual(a, '0b0') a = BitStream(1007) self.assertEqual(a, BitStream(length=1007)) self.assertRaises(bitstring.CreationError, BitStream, -1) a = 6 + ConstBitStream('0b1') + 3 self.assertEqual(a, '0b0000001000') a += 1 self.assertEqual(a, '0b00000010000') self.assertEqual(ConstBitStream(13), 13) def testReadingProblems(self): a = BitStream('0x000001') b = a.read('uint:24') self.assertEqual(b, 1) a.pos = 0 self.assertRaises(bitstring.ReadError, a.read, 'bytes:4') def testAddVersesInPlaceAdd(self): a1 = ConstBitStream('0xabc') b1 = a1 a1 += '0xdef' self.assertEqual(a1, '0xabcdef') self.assertEqual(b1, '0xabc') a2 = BitStream('0xabc') b2 = a2 c2 = a2 + '0x0' a2 += '0xdef' self.assertEqual(a2, '0xabcdef') self.assertEqual(b2, '0xabcdef') self.assertEqual(c2, '0xabc0') def testAndVersesInPlaceAnd(self): a1 = ConstBitStream('0xabc') b1 = a1 a1 &= '0xf0f' self.assertEqual(a1, '0xa0c') self.assertEqual(b1, '0xabc') a2 = BitStream('0xabc') b2 = a2 c2 = a2 & '0x00f' a2 &= '0xf0f' self.assertEqual(a2, '0xa0c') self.assertEqual(b2, '0xa0c') self.assertEqual(c2, '0x00c') def testOrVersesInPlaceOr(self): a1 = ConstBitStream('0xabc') b1 = a1 a1 |= '0xf0f' self.assertEqual(a1, '0xfbf') self.assertEqual(b1, '0xabc') a2 = BitStream('0xabc') b2 = a2 c2 = a2 | '0x00f' a2 |= '0xf0f' self.assertEqual(a2, '0xfbf') self.assertEqual(b2, '0xfbf') self.assertEqual(c2, '0xabf') def testXorVersesInPlaceXor(self): a1 = ConstBitStream('0xabc') b1 = a1 a1 ^= '0xf0f' self.assertEqual(a1, '0x5b3') self.assertEqual(b1, '0xabc') a2 = BitStream('0xabc') b2 = a2 c2 = a2 ^ '0x00f' a2 ^= '0xf0f' self.assertEqual(a2, '0x5b3') self.assertEqual(b2, '0x5b3') self.assertEqual(c2, '0xab3') def testMulVersesInPlaceMul(self): a1 = ConstBitStream('0xabc') b1 = a1 a1 *= 3 self.assertEqual(a1, '0xabcabcabc') self.assertEqual(b1, '0xabc') a2 = BitStream('0xabc') b2 = a2 c2 = a2 * 2 a2 *= 3 self.assertEqual(a2, '0xabcabcabc') self.assertEqual(b2, '0xabcabcabc') self.assertEqual(c2, '0xabcabc') def testLshiftVersesInPlaceLshift(self): a1 = ConstBitStream('0xabc') b1 = a1 a1 <<= 4 self.assertEqual(a1, '0xbc0') self.assertEqual(b1, '0xabc') a2 = BitStream('0xabc') b2 = a2 c2 = a2 << 8 a2 <<= 4 self.assertEqual(a2, '0xbc0') self.assertEqual(b2, '0xbc0') self.assertEqual(c2, '0xc00') def testRshiftVersesInPlaceRshift(self): a1 = ConstBitStream('0xabc') b1 = a1 a1 >>= 4 self.assertEqual(a1, '0x0ab') self.assertEqual(b1, '0xabc') a2 = BitStream('0xabc') b2 = a2 c2 = a2 >> 8 a2 >>= 4 self.assertEqual(a2, '0x0ab') self.assertEqual(b2, '0x0ab') self.assertEqual(c2, '0x00a') def testAutoFromBool(self): a = ConstBitStream() + True + False + True self.assertEqual(a, '0b00') # self.assertEqual(a, '0b101') # b = ConstBitStream(False) # self.assertEqual(b, '0b0') # c = ConstBitStream(True) # self.assertEqual(c, '0b1') # self.assertEqual(b, False) # self.assertEqual(c, True) # self.assertEqual(b & True, False) class Bugs(unittest.TestCase): def testBugInReplace(self): s = BitStream('0x00112233') l = list(s.split('0x22', start=8, bytealigned=True)) self.assertEqual(l, ['0x11', '0x2233']) s = BitStream('0x00112233') s.replace('0x22', '0xffff', start=8, bytealigned=True) self.assertEqual(s, '0x0011ffff33') s = BitStream('0x0123412341234') s.replace('0x23', '0xf', start=9, bytealigned=True) self.assertEqual(s, '0x012341f41f4') def testTruncateStartBug(self): a = BitStream('0b000000111')[2:] a._truncatestart(6) self.assertEqual(a, '0b1') def testNullBits(self): s = ConstBitStream(bin='') t = ConstBitStream(oct='') u = ConstBitStream(hex='') v = ConstBitStream(bytes=b'') self.assertFalse(s) self.assertFalse(t) self.assertFalse(u) self.assertFalse(v) def testMultiplicativeFactorsCreation(self): s = BitStream('1*0b1') self.assertEqual(s, '0b1') s = BitStream('4*0xc') self.assertEqual(s, '0xcccc') s = BitStream('0b1, 0*0b0') self.assertEqual(s, '0b1') s = BitStream('0b1, 3*uint:8=34, 2*0o755') self.assertEqual(s, '0b1, uint:8=34, uint:8=34, uint:8=34, 0o755755') s = BitStream('0*0b1001010') self.assertFalse(s) def testMultiplicativeFactorsReading(self): s = BitStream('0xc') * 5 a, b, c, d, e = s.readlist('5*4') self.assertTrue(a == b == c == d == e == 12) s = ConstBitStream('2*0b101, 4*uint:7=3') a, b, c, d, e = s.readlist('2*bin:3, 3*uint:7') self.assertTrue(a == b == '101') self.assertTrue(c == d == e == 3) def testMultiplicativeFactorsPacking(self): s = pack('3*bin', '1', '001', '101') self.assertEqual(s, '0b1001101') s = pack('hex, 2*se=-56, 3*uint:37', '34', 1, 2, 3) a, b, c, d, e, f = s.unpack('hex:8, 2*se, 3*uint:37') self.assertEqual(a, '34') self.assertEqual(b, -56) self.assertEqual(c, -56) self.assertEqual((d, e, f), (1, 2, 3)) # This isn't allowed yet. See comment in tokenparser. #s = pack('fluffy*uint:8', *range(3), fluffy=3) #a, b, c = s.readlist('2*uint:8, 1*uint:8, 0*uint:8') #self.assertEqual((a, b, c), (0, 1, 2)) def testMultiplicativeFactorsUnpacking(self): s = ConstBitStream('0b10111') a, b, c, d = s.unpack('3*bool, bin') self.assertEqual((a, b, c), (True, False, True)) self.assertEqual(d, '11') def testPackingDefaultIntWithKeyword(self): s = pack('12', 100) self.assertEqual(s.unpack('12')[0], 100) s = pack('oh_no_not_the_eyes=33', oh_no_not_the_eyes=17) self.assertEqual(s.uint, 33) self.assertEqual(s.len, 17) def testInitFromIterable(self): self.assertTrue(isinstance(range(10), collections.Iterable)) s = ConstBitStream(range(12)) self.assertEqual(s, '0x7ff') def testFunctionNegativeIndices(self): # insert s = BitStream('0b0111') s.insert('0b0', -1) self.assertEqual(s, '0b01101') self.assertRaises(ValueError, s.insert, '0b0', -1000) # reverse s.reverse(-2) self.assertEqual(s, '0b01110') t = BitStream('0x778899abcdef') t.reverse(-12, -4) self.assertEqual(t, '0x778899abc7bf') # reversebytes t.byteswap(0, -40, -16) self.assertEqual(t, '0x77ab9988c7bf') # overwrite t.overwrite('0x666', -20) self.assertEqual(t, '0x77ab998666bf') # find found = t.find('0x998', bytealigned=True, start=-31) self.assertFalse(found) found = t.find('0x998', bytealigned=True, start=-32) self.assertTrue(found) self.assertEqual(t.pos, 16) t.pos = 0 found = t.find('0x988', bytealigned=True, end=-21) self.assertFalse(found) found = t.find('0x998', bytealigned=True, end=-20) self.assertTrue(found) self.assertEqual(t.pos, 16) #findall s = BitStream('0x1234151f') l = list(s.findall('0x1', bytealigned=True, start=-15)) self.assertEqual(l, [24]) l = list(s.findall('0x1', bytealigned=True, start=-16)) self.assertEqual(l, [16, 24]) l = list(s.findall('0x1', bytealigned=True, end=-5)) self.assertEqual(l, [0, 16]) l = list(s.findall('0x1', bytealigned=True, end=-4)) self.assertEqual(l, [0, 16, 24]) # rfind found = s.rfind('0x1f', end=-1) self.assertFalse(found) found = s.rfind('0x12', start=-31) self.assertFalse(found) # cut s = BitStream('0x12345') l = list(s.cut(4, start=-12, end=-4)) self.assertEqual(l, ['0x3', '0x4']) # split s = BitStream('0xfe0012fe1200fe') l = list(s.split('0xfe', bytealigned=True, end=-1)) self.assertEqual(l, ['', '0xfe0012', '0xfe1200f, 0b111']) l = list(s.split('0xfe', bytealigned=True, start=-8)) self.assertEqual(l, ['', '0xfe']) # startswith self.assertTrue(s.startswith('0x00f', start=-16)) self.assertTrue(s.startswith('0xfe00', end=-40)) self.assertFalse(s.startswith('0xfe00', end=-41)) # endswith self.assertTrue(s.endswith('0x00fe', start=-16)) self.assertFalse(s.endswith('0x00fe', start=-15)) self.assertFalse(s.endswith('0x00fe', end=-1)) self.assertTrue(s.endswith('0x00f', end=-4)) # replace s.replace('0xfe', '', end=-1) self.assertEqual(s, '0x00121200fe') s.replace('0x00', '', start=-24) self.assertEqual(s, '0x001212fe') def testRotateStartAndEnd(self): a = BitStream('0b110100001') a.rol(1, 3, 6) self.assertEqual(a, '0b110001001') a.ror(1, start=-4) self.assertEqual(a, '0b110001100') a.rol(202, end=-5) self.assertEqual(a, '0b001101100') a.ror(3, end=4) self.assertEqual(a, '0b011001100') self.assertRaises(ValueError, a.rol, 5, start=-4, end=-6) def testByteSwapInt(self): s = pack('5*uintle:16', *range(10, 15)) self.assertEqual(list(range(10, 15)), s.unpack('5*uintle:16')) swaps = s.byteswap(2) self.assertEqual(list(range(10, 15)), s.unpack('5*uintbe:16')) self.assertEqual(swaps, 5) s = BitStream('0xf234567f') swaps = s.byteswap(1, start=4) self.assertEqual(swaps, 3) self.assertEqual(s, '0xf234567f') s.byteswap(2, start=4) self.assertEqual(s, '0xf452367f') s.byteswap(2, start=4, end=-4) self.assertEqual(s, '0xf234567f') s.byteswap(3) self.assertEqual(s, '0x5634f27f') s.byteswap(2, repeat=False) self.assertEqual(s, '0x3456f27f') swaps = s.byteswap(5) self.assertEqual(swaps, 0) swaps = s.byteswap(4, repeat=False) self.assertEqual(swaps, 1) self.assertEqual(s, '0x7ff25634') def testByteSwapPackCode(self): s = BitStream('0x0011223344556677') swaps = s.byteswap('b') self.assertEqual(s, '0x0011223344556677') self.assertEqual(swaps, 8) swaps = s.byteswap('>3h', repeat=False) self.assertEqual(s, '0x1100332255446677') self.assertEqual(swaps, 1) def testByteSwapIterable(self): s = BitStream('0x0011223344556677') swaps = s.byteswap(range(1, 4), repeat=False) self.assertEqual(swaps, 1) self.assertEqual(s, '0x0022115544336677') swaps = s.byteswap([2], start=8) self.assertEqual(s, '0x0011224455663377') self.assertEqual(3, swaps) swaps = s.byteswap([2, 3], start=4) self.assertEqual(swaps, 1) self.assertEqual(s, '0x0120156452463377') def testByteSwapErrors(self): s = BitStream('0x0011223344556677') self.assertRaises(ValueError, s.byteswap, 'z') self.assertRaises(ValueError, s.byteswap, -1) self.assertRaises(ValueError, s.byteswap, [-1]) self.assertRaises(ValueError, s.byteswap, [1, 'e']) self.assertRaises(ValueError, s.byteswap, '!h') self.assertRaises(ValueError, s.byteswap, 2, start=-1000) self.assertRaises(TypeError, s.byteswap, 5.4) def testByteSwapFromFile(self): s = BitStream(filename='smalltestfile') swaps = s.byteswap('2bh') self.assertEqual(s, '0x0123674589abefcd') self.assertEqual(swaps, 2) def testBracketExpander(self): be = bitstring.expand_brackets self.assertEqual(be('hello'), 'hello') self.assertEqual(be('(hello)'), 'hello') self.assertEqual(be('1*(hello)'), 'hello') self.assertEqual(be('2*(hello)'), 'hello,hello') self.assertEqual(be('1*(a, b)'), 'a,b') self.assertEqual(be('2*(a, b)'), 'a,b,a,b') self.assertEqual(be('2*(a), 3*(b)'), 'a,a,b,b,b') self.assertEqual(be('2*(a, b, 3*(c, d), e)'), 'a,b,c,d,c,d,c,d,e,a,b,c,d,c,d,c,d,e') def testBracketTokens(self): s = BitStream('3*(0x0, 0b1)') self.assertEqual(s, '0x0, 0b1, 0x0, 0b1, 0x0, 0b1') s = pack('2*(uint:12, 3*(7, 6))', *range(3, 17)) a = s.unpack('12, 7, 6, 7, 6, 7, 6, 12, 7, 6, 7, 6, 7, 6') self.assertEqual(a, list(range(3, 17))) b = s.unpack('2*(12,3*(7,6))') self.assertEqual(a, b) def testPackCodeDicts(self): self.assertEqual(sorted(bitstring.REPLACEMENTS_BE.keys()), sorted(bitstring.REPLACEMENTS_LE.keys())) self.assertEqual(sorted(bitstring.REPLACEMENTS_BE.keys()), sorted(bitstring.PACK_CODE_SIZE.keys())) for key in bitstring.PACK_CODE_SIZE: be = pack(bitstring.REPLACEMENTS_BE[key], 0) le = pack(bitstring.REPLACEMENTS_LE[key], 0) self.assertEqual(be.len, bitstring.PACK_CODE_SIZE[key] * 8) self.assertEqual(le.len, be.len) # These tests don't compile for Python 3, so they're commented out to save me stress. #def testUnicode(self): #a = ConstBitStream(u'uint:12=34') #self.assertEqual(a.uint, 34) #a += u'0xfe' #self.assertEqual(a[12:], '0xfe') #a = BitStream('0x1122') #c = a.byteswap(u'h') #self.assertEqual(c, 1) #self.assertEqual(a, u'0x2211') #def testLongInt(self): #a = BitStream(4L) #self.assertEqual(a, '0b0000') #a[1:3] = -1L #self.assertEqual(a, '0b0110') #a[0] = 1L #self.assertEqual(a, '0b1110') #a *= 4L #self.assertEqual(a, '0xeeee') #c = a.byteswap(2L) #self.assertEqual(c, 1) #a = BitStream('0x11223344') #a.byteswap([1, 2L]) #self.assertEqual(a, '0x11332244') #b = a*2L #self.assertEqual(b, '0x1133224411332244') #s = pack('uint:12', 46L) #self.assertEqual(s.uint, 46) class UnpackWithDict(unittest.TestCase): def testLengthKeywords(self): a = ConstBitStream('2*13=100, 0b111') x, y, z = a.unpack('n, uint:m, bin:q', n=13, m=13, q=3) self.assertEqual(x, 100) self.assertEqual(y, 100) self.assertEqual(z, '111') def testLengthKeywordsWithStretch(self): a = ConstBitStream('0xff, 0b000, 0xf') x, y, z = a.unpack('hex:a, bin, hex:b', a=8, b=4) self.assertEqual(y, '000') def testUnusedKeyword(self): a = ConstBitStream('0b110') x, = a.unpack('bin:3', notused=33) self.assertEqual(x, '110') def testLengthKeywordErrors(self): a = pack('uint:p=33', p=12) self.assertRaises(ValueError, a.unpack, 'uint:p') self.assertRaises(ValueError, a.unpack, 'uint:p', p='a_string') class ReadWithDict(unittest.TestCase): def testLengthKeywords(self): s = BitStream('0x0102') x, y = s.readlist('a, hex:b', a=8, b=4) self.assertEqual((x, y), (1, '0')) self.assertEqual(s.pos, 12) def testBytesKeywordProblem(self): s = BitStream('0x01') x, = s.unpack('bytes:a', a=1) self.assertEqual(x, b'\x01') s = BitStream('0x000ff00a') x, y, z = s.unpack('12, bytes:x, bits', x=2) self.assertEqual((x, y, z), (0, b'\xff\x00', '0xa')) class PeekWithDict(unittest.TestCase): def testLengthKeywords(self): s = BitStream('0x0102') x, y = s.peeklist('a, hex:b', a=8, b=4) self.assertEqual((x, y), (1, '0')) self.assertEqual(s.pos, 0) ##class Miscellany(unittest.TestCase): ## ## def testNumpyInt(self): ## try: ## import numpy ## a = ConstBitStream(uint=numpy.uint8(5), length=3) ## self.assertEqual(a.uint, 5) ## except ImportError: ## # Not to worry ## pass class BoolToken(unittest.TestCase): def testInterpretation(self): a = ConstBitStream('0b1') self.assertEqual(a.bool, True) self.assertEqual(a.read('bool'), True) self.assertEqual(a.unpack('bool')[0], True) b = ConstBitStream('0b0') self.assertEqual(b.bool, False) self.assertEqual(b.peek('bool'), False) self.assertEqual(b.unpack('bool')[0], False) def testPack(self): a = pack('bool=True') b = pack('bool=False') self.assertEqual(a.bool, True) self.assertEqual(b.bool, False) c = pack('4*bool', False, True, 'False', 'True') self.assertEqual(c, '0b0101') def testAssignment(self): a = BitStream() a.bool = True self.assertEqual(a.bool, True) a.hex = 'ee' a.bool = False self.assertEqual(a.bool, False) a.bool = 'False' self.assertEqual(a.bool, False) a.bool = 'True' self.assertEqual(a.bool, True) a.bool = 0 self.assertEqual(a.bool, False) a.bool = 1 self.assertEqual(a.bool, True) def testErrors(self): self.assertRaises(bitstring.CreationError, pack, 'bool', 'hello') self.assertRaises(bitstring.CreationError, pack, 'bool=true') self.assertRaises(bitstring.CreationError, pack, 'True') self.assertRaises(bitstring.CreationError, pack, 'bool', 2) a = BitStream('0b11') self.assertRaises(bitstring.InterpretError, a._getbool) b = BitStream() self.assertRaises(bitstring.InterpretError, a._getbool) self.assertRaises(bitstring.CreationError, a._setbool, 'false') def testLengthWithBoolRead(self): a = ConstBitStream('0xf') self.assertRaises(ValueError, a.read, 'bool:0') self.assertRaises(ValueError, a.read, 'bool:1') self.assertRaises(ValueError, a.read, 'bool:2') class ReadWithIntegers(unittest.TestCase): def testReadInt(self): a = ConstBitStream('0xffeedd') b = a.read(8) self.assertEqual(b.hex, 'ff') self.assertEqual(a.pos, 8) b = a.peek(8) self.assertEqual(b.hex, 'ee') self.assertEqual(a.pos, 8) b = a.peek(1) self.assertEqual(b, '0b1') b = a.read(1) self.assertEqual(b, '0b1') def testReadIntList(self): a = ConstBitStream('0xab, 0b110') b, c = a.readlist([8, 3]) self.assertEqual(b.hex, 'ab') self.assertEqual(c.bin, '110') class FileReadingStrategy(unittest.TestCase): def testBitStreamIsAlwaysRead(self): a = BitStream(filename='smalltestfile') self.assertTrue(isinstance(a._datastore, bitstring.ByteStore)) f = open('smalltestfile', 'rb') b = BitStream(f) self.assertTrue(isinstance(b._datastore, bitstring.ByteStore)) def testBitsIsNeverRead(self): a = ConstBitStream(filename='smalltestfile') self.assertTrue(isinstance(a._datastore._rawarray, bitstring.MmapByteArray)) f = open('smalltestfile', 'rb') b = ConstBitStream(f) self.assertTrue(isinstance(b._datastore._rawarray, bitstring.MmapByteArray)) class Count(unittest.TestCase): def testCount(self): a = ConstBitStream('0xf0f') self.assertEqual(a.count(True), 8) self.assertEqual(a.count(False), 4) b = BitStream() self.assertEqual(b.count(True), 0) self.assertEqual(b.count(False), 0) def testCountWithOffsetData(self): a = ConstBitStream('0xff0120ff') b = a[1:-1] self.assertEqual(b.count(1), 16) self.assertEqual(b.count(0), 14) class ZeroBitReads(unittest.TestCase): def testInteger(self): a = ConstBitStream('0x123456') self.assertRaises(bitstring.InterpretError, a.read, 'uint:0') self.assertRaises(bitstring.InterpretError, a.read, 'float:0') #class EfficientBitsCopies(unittest.TestCase): # # def testBitsCopy(self): # a = ConstBitStream('0xff') # b = ConstBitStream(a) # c = a[:] # d = copy.copy(a) # self.assertTrue(a._datastore is b._datastore) # self.assertTrue(a._datastore is c._datastore) # self.assertTrue(a._datastore is d._datastore) class InitialiseFromBytes(unittest.TestCase): def testBytesBehaviour(self): a = ConstBitStream(b'uint:5=2') b = ConstBitStream(b'') c = ConstBitStream(bytes=b'uint:5=2') if b'' == '': # Python 2 self.assertEqual(a, 'uint:5=2') self.assertFalse(b) self.assertEqual(c.bytes, b'uint:5=2') else: self.assertEqual(a.bytes, b'uint:5=2') self.assertFalse(b) self.assertEqual(c, b'uint:5=2') def testBytearrayBehaviour(self): a = ConstBitStream(bytearray(b'uint:5=2')) b = ConstBitStream(bytearray(4)) c = ConstBitStream(bytes=bytearray(b'uint:5=2')) self.assertEqual(a.bytes, b'uint:5=2') self.assertEqual(b, '0x00000000') self.assertEqual(c.bytes, b'uint:5=2') class CoverageCompletionTests(unittest.TestCase): def testUeReadError(self): s = ConstBitStream('0b000000001') self.assertRaises(bitstring.ReadError, s.read, 'ue') def testOverwriteWithSelf(self): s = BitStream('0b1101') s.overwrite(s) self.assertEqual(s, '0b1101') class Subclassing(unittest.TestCase): def testIsInstance(self): class SubBits(BitStream): pass a = SubBits() self.assertTrue(isinstance(a, SubBits)) def testClassType(self): class SubBits(BitStream): pass self.assertEqual(SubBits().__class__, SubBits) class BytesProblems(unittest.TestCase): def testOffsetButNoLength(self): b = BitStream(bytes=b'\x00\xaa', offset=8) self.assertEqual(b.hex, 'aa') b = BitStream(bytes=b'\x00\xaa', offset=4) self.assertEqual(b.hex, '0aa') def testInvert(self): b = BitStream(bytes=b'\x00\xaa', offset=8, length=8) self.assertEqual(b.hex, 'aa') b.invert() self.assertEqual(b.hex, '55') def testPrepend(self): b = BitStream(bytes=b'\xaa\xbb', offset=8, length=4) self.assertEqual(b.hex, 'b') b.prepend('0xe') self.assertEqual(b.hex, 'eb') b = BitStream(bytes=b'\x00\xaa', offset=8, length=8) b.prepend('0xee') self.assertEqual(b.hex, 'eeaa') def testByteSwap(self): b = BitStream(bytes=b'\x01\x02\x03\x04', offset=8) b.byteswap() self.assertEqual(b, '0x040302') def testBinProperty(self): b = BitStream(bytes=b'\x00\xaa', offset=8, length=4) self.assertEqual(b.bin, '1010')