Package lepl :: Package bin :: Module bits
[hide private]
[frames] | no frames]

Module bits

source code

Storage of binary values of arbitrary length.

Endianness is an issue here because we want to naturally "do the right thing" and unfortunately this varies, depending on context. Most target hardware (x86) is little-endian, but network protocols are typically big-endian.

I personally prefer big-endian for long hex strings - it seems obvious that 0x123456 should be encoded as [0x12, 0x34, 0x56]. On the other hand, it also seems reasonable that the integer 1193046 (=0x123456) should be stored small-endian as [0x56, 0x34, 0x12, 0x00] because that is how it is stored in memory. Unfortunately we cannot implement both because integer values do not contain any flag to say how the user specified them (hex or decimal).

A very similar issue - that integers do not carry any information to say how many leading zeroes were entered by the user - suggests a solution to this problem. To solve the leading zeroes issue we accept integers as strings and do the conversion ourselves. Since we are dealing with strings we can invent an entirely new encoding to specify endianness. We will use little-endian for ints and the "usual" notation since this reflects the hardware (it appeals to the idea that we are simply taking the chunk of memory in which the integer existed and using it directly). For big endian, we will use a trailing type flag (ie change "ends") in strings.

So 1193046, "1193046", 0x123456, "0x123456" all encode to [0x56, 0x34, 0x12] (module some questions about implicit/explicit lengths).

But "123456x0" encodes to [0x12, 0x34, 0x56]. This does have a slight wrinkle - 100b0 looks like a hex value (but is not, as it does not start with 0x).

Note: No attempt is made to handle sign (complements etc).

Classes [hide private]
  Int
An integer with a length (the number of bits).
  BitString
A sequence of bits, of arbitrary length.
  BitIterator
A sequence of bits (used by BitString).
  ByteIterator
A sequence of bytes (used by BitString).
Functions [hide private]
 
swap_table()
Table of reversed bit patterns for 8 bits.
source code
 
unpack_length(length)
Length is in bits, unless a decimal is specified, in which case it it has the structure bytes.bits.
source code
 
bytes_for_bits(bits, offset=0)
The number of bytes required to specify the given number of bits.
source code
Variables [hide private]
  STRICT = 'strict'
  ONE = BitString(b '\x01', 1)
  ZERO = BitString(b '\x00', 1)
Function Details [hide private]

unpack_length(length)

source code 
Length is in bits, unless a decimal is specified, in which case it it has the structure bytes.bits. Obviously this is ambiguous with float values (eg 3.1 or 3.10), but since we only care about bits 0-7 we can avoid any issues by requiring that range.