Simplified Python code by making BitBuffer subclass list, updated internal usages.
This commit is contained in:
parent
ac10dc21ce
commit
a341901d94
|
@ -120,18 +120,18 @@ class QrCode(object):
|
||||||
for seg in segs:
|
for seg in segs:
|
||||||
bb.append_bits(seg.get_mode().get_mode_bits(), 4)
|
bb.append_bits(seg.get_mode().get_mode_bits(), 4)
|
||||||
bb.append_bits(seg.get_num_chars(), seg.get_mode().num_char_count_bits(version))
|
bb.append_bits(seg.get_num_chars(), seg.get_mode().num_char_count_bits(version))
|
||||||
bb.append_all(seg)
|
bb.extend(seg._bitdata)
|
||||||
|
|
||||||
# Add terminator and pad up to a byte if applicable
|
# Add terminator and pad up to a byte if applicable
|
||||||
bb.append_bits(0, min(4, datacapacitybits - bb.bit_length()))
|
bb.append_bits(0, min(4, datacapacitybits - len(bb)))
|
||||||
bb.append_bits(0, -bb.bit_length() % 8) # Note: Python's modulo on negative numbers behaves better than C family languages
|
bb.append_bits(0, -len(bb) % 8) # Note: Python's modulo on negative numbers behaves better than C family languages
|
||||||
|
|
||||||
# Pad with alternate bytes until data capacity is reached
|
# Pad with alternate bytes until data capacity is reached
|
||||||
for padbyte in itertools.cycle((0xEC, 0x11)):
|
for padbyte in itertools.cycle((0xEC, 0x11)):
|
||||||
if bb.bit_length() >= datacapacitybits:
|
if len(bb) >= datacapacitybits:
|
||||||
break
|
break
|
||||||
bb.append_bits(padbyte, 8)
|
bb.append_bits(padbyte, 8)
|
||||||
assert bb.bit_length() % 8 == 0
|
assert len(bb) % 8 == 0
|
||||||
|
|
||||||
# Create the QR Code symbol
|
# Create the QR Code symbol
|
||||||
return QrCode(None, bb.get_bytes(), mask, version, ecl)
|
return QrCode(None, bb.get_bytes(), mask, version, ecl)
|
||||||
|
@ -619,7 +619,7 @@ class QrSegment(object):
|
||||||
bb = _BitBuffer()
|
bb = _BitBuffer()
|
||||||
for b in data:
|
for b in data:
|
||||||
bb.append_bits(b, 8)
|
bb.append_bits(b, 8)
|
||||||
return QrSegment(QrSegment.Mode.BYTE, len(data), bb.get_bits())
|
return QrSegment(QrSegment.Mode.BYTE, len(data), bb)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -633,7 +633,7 @@ class QrSegment(object):
|
||||||
rem = len(digits) % 3
|
rem = len(digits) % 3
|
||||||
if rem > 0: # 1 or 2 digits remaining
|
if rem > 0: # 1 or 2 digits remaining
|
||||||
bb.append_bits(int(digits[-rem : ]), rem * 3 + 1)
|
bb.append_bits(int(digits[-rem : ]), rem * 3 + 1)
|
||||||
return QrSegment(QrSegment.Mode.NUMERIC, len(digits), bb.get_bits())
|
return QrSegment(QrSegment.Mode.NUMERIC, len(digits), bb)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -649,7 +649,7 @@ class QrSegment(object):
|
||||||
bb.append_bits(temp, 11)
|
bb.append_bits(temp, 11)
|
||||||
if len(text) % 2 > 0: # 1 character remaining
|
if len(text) % 2 > 0: # 1 character remaining
|
||||||
bb.append_bits(QrSegment._ALPHANUMERIC_ENCODING_TABLE[text[-1]], 6)
|
bb.append_bits(QrSegment._ALPHANUMERIC_ENCODING_TABLE[text[-1]], 6)
|
||||||
return QrSegment(QrSegment.Mode.ALPHANUMERIC, len(text), bb.get_bits())
|
return QrSegment(QrSegment.Mode.ALPHANUMERIC, len(text), bb)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -685,7 +685,7 @@ class QrSegment(object):
|
||||||
bb.append_bits(assignval, 21)
|
bb.append_bits(assignval, 21)
|
||||||
else:
|
else:
|
||||||
raise ValueError("ECI assignment value out of range")
|
raise ValueError("ECI assignment value out of range")
|
||||||
return QrSegment(QrSegment.Mode.ECI, 0, bb.get_bits())
|
return QrSegment(QrSegment.Mode.ECI, 0, bb)
|
||||||
|
|
||||||
|
|
||||||
# ---- Constructor ----
|
# ---- Constructor ----
|
||||||
|
@ -721,7 +721,7 @@ class QrSegment(object):
|
||||||
# Fail if segment length value doesn't fit in the length field's bit-width
|
# Fail if segment length value doesn't fit in the length field's bit-width
|
||||||
if seg.get_num_chars() >= (1 << ccbits):
|
if seg.get_num_chars() >= (1 << ccbits):
|
||||||
return None
|
return None
|
||||||
result += 4 + ccbits + len(seg.get_bits())
|
result += 4 + ccbits + len(seg._bitdata)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@ -828,25 +828,13 @@ class _ReedSolomonGenerator(object):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class _BitBuffer(object):
|
class _BitBuffer(list):
|
||||||
"""An appendable sequence of bits. Bits are packed in big endian within a byte."""
|
"""An appendable sequence of bits (0's and 1's)."""
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""Creates an empty bit buffer (length 0)."""
|
|
||||||
self.data = [] # Only contains 0s and 1s
|
|
||||||
|
|
||||||
def bit_length(self):
|
|
||||||
"""Returns the number of bits in the buffer, which is a non-negative value."""
|
|
||||||
return len(self.data)
|
|
||||||
|
|
||||||
def get_bits(self):
|
|
||||||
"""Returns a copy of all bits."""
|
|
||||||
return list(self.data)
|
|
||||||
|
|
||||||
def get_bytes(self):
|
def get_bytes(self):
|
||||||
"""Returns a copy of all bytes, padding up to the nearest byte."""
|
"""Returns a copy of all bytes, padding up to the nearest byte. Bits are packed in big endian within a byte."""
|
||||||
result = [0] * ((len(self.data) + 7) // 8)
|
result = [0] * ((len(self) + 7) // 8)
|
||||||
for (i, bit) in enumerate(self.data):
|
for (i, bit) in enumerate(self):
|
||||||
result[i >> 3] |= bit << (7 - (i & 7))
|
result[i >> 3] |= bit << (7 - (i & 7))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -854,10 +842,4 @@ class _BitBuffer(object):
|
||||||
"""Appends the given number of bits of the given value to this sequence. This requires 0 <= val < 2^n."""
|
"""Appends the given number of bits of the given value to this sequence. This requires 0 <= val < 2^n."""
|
||||||
if n < 0 or val >> n != 0:
|
if n < 0 or val >> n != 0:
|
||||||
raise ValueError("Value out of range")
|
raise ValueError("Value out of range")
|
||||||
self.data.extend(((val >> i) & 1) for i in reversed(range(n)))
|
self.extend(((val >> i) & 1) for i in reversed(range(n)))
|
||||||
|
|
||||||
def append_all(self, seg):
|
|
||||||
"""Appends the data of the given segment to this bit buffer."""
|
|
||||||
if not isinstance(seg, QrSegment):
|
|
||||||
raise TypeError("QrSegment expected")
|
|
||||||
self.data.extend(seg.get_bits())
|
|
||||||
|
|
Loading…
Reference in New Issue