add code documentation
This commit is contained in:
parent
535ef1d42b
commit
1eba1c7196
|
@ -1,2 +1,3 @@
|
||||||
__pycache__
|
__pycache__
|
||||||
*.bak
|
*.bak
|
||||||
|
*.swp
|
||||||
|
|
217
bits/main.py
217
bits/main.py
|
@ -5,6 +5,14 @@ class Bit:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, var):
|
def __init__(self, var):
|
||||||
|
"""
|
||||||
|
var: Any supported type
|
||||||
|
Supported types: (bool, int, str, Bit)
|
||||||
|
bool: True or False
|
||||||
|
int: 0 = False, anything else = True
|
||||||
|
str: "0" = False, anything else = True
|
||||||
|
Bit: Bit = Bit
|
||||||
|
"""
|
||||||
if not isinstance(var, (bool, int, str, Bit)):
|
if not isinstance(var, (bool, int, str, Bit)):
|
||||||
raise TypeError("Bit must be one of type (int, bool, str)")
|
raise TypeError("Bit must be one of type (int, bool, str)")
|
||||||
if isinstance(var, (int, Bit)):
|
if isinstance(var, (int, Bit)):
|
||||||
|
@ -20,6 +28,9 @@ class Bit:
|
||||||
self.__bit = var
|
self.__bit = var
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
"""
|
||||||
|
Return "0" or "1"
|
||||||
|
"""
|
||||||
return str(int(self.__bit))
|
return str(int(self.__bit))
|
||||||
|
|
||||||
def __int__(self):
|
def __int__(self):
|
||||||
|
@ -29,9 +40,12 @@ class Bit:
|
||||||
return self.__bit
|
return self.__bit
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'{self.__class__.__name__}({self.__bit!r})'
|
return f'{self.__class__.__name__}({int(self.__bit)})'
|
||||||
|
|
||||||
def __eq__(self, compare):
|
def __eq__(self, compare):
|
||||||
|
"""
|
||||||
|
compare (self) to any supported object
|
||||||
|
"""
|
||||||
# Massage compare to bool
|
# Massage compare to bool
|
||||||
return bool(self) == bool(Bit(compare))
|
return bool(self) == bool(Bit(compare))
|
||||||
|
|
||||||
|
@ -54,15 +68,21 @@ class Bit:
|
||||||
return self.__bit
|
return self.__bit
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
|
"""
|
||||||
|
Not very useful, but provided nonetheless
|
||||||
|
"""
|
||||||
return hash(self.__bit)
|
return hash(self.__bit)
|
||||||
|
|
||||||
def toggle(self):
|
def toggle(self):
|
||||||
|
"""
|
||||||
|
(self) = Not (Self)
|
||||||
|
"""
|
||||||
self.__bit = not self.__bit
|
self.__bit = not self.__bit
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def lie(self):
|
def lie(self):
|
||||||
"""
|
"""
|
||||||
Return the opposite of bit, without changing the bit state
|
Return the opposite of bit, without changing the state of (self)
|
||||||
"""
|
"""
|
||||||
return not self.__bit
|
return not self.__bit
|
||||||
|
|
||||||
|
@ -73,23 +93,43 @@ class Bits:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, var=0, msb_last=False):
|
def __init__(self, var=0, msb_last=False):
|
||||||
|
"""
|
||||||
|
var: any supported variant type that can be interpreted as Bits object
|
||||||
|
msb_last: True to swap bit order for indexing and slicing. Equivalent
|
||||||
|
to Bits(Bits(var).stib)
|
||||||
|
"""
|
||||||
self.__value = 0
|
self.__value = 0
|
||||||
self.__r_to_l = bool(msb_last)
|
self.__r_to_l = bool(msb_last)
|
||||||
self.__setvalue(var)
|
self.__setvalue(var)
|
||||||
|
|
||||||
def __bytes__(self):
|
def __bytes__(self):
|
||||||
|
"""
|
||||||
|
Get copy(self) as binary object
|
||||||
|
"""
|
||||||
return bytes([self.__value])
|
return bytes([self.__value])
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
|
"""
|
||||||
|
False if self = Bit(0), otherwise True if self > 0
|
||||||
|
Use indexing to get value of specific bit, e.g. self[1] will return
|
||||||
|
Bit(1) if self = "01000000" (left to right)
|
||||||
|
Use self.stib[1] to get bit 6 in Bit("00000010")
|
||||||
|
"""
|
||||||
return bool(int(self))
|
return bool(int(self))
|
||||||
|
|
||||||
def __int__(self):
|
def __int__(self):
|
||||||
|
"""
|
||||||
|
Get integer value of self
|
||||||
|
"""
|
||||||
return self.__value
|
return self.__value
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'{self.__class__.__name__}({self.__value!r})'
|
return f'{self.__class__.__name__}({self.__value!r})'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
"""
|
||||||
|
Get binary string representation of self
|
||||||
|
"""
|
||||||
return self.bin()
|
return self.bin()
|
||||||
|
|
||||||
def __ord__(self):
|
def __ord__(self):
|
||||||
|
@ -120,9 +160,19 @@ class Bits:
|
||||||
return int(self) >= int(Bits(compare))
|
return int(self) >= int(Bits(compare))
|
||||||
|
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
|
"""
|
||||||
|
Get Bit at index from self
|
||||||
|
"""
|
||||||
return self.list()[index]
|
return self.list()[index]
|
||||||
|
|
||||||
def __setitem__(self, index, value):
|
def __setitem__(self, index, value):
|
||||||
|
"""
|
||||||
|
Change value of self by setting or resetting a single Bit
|
||||||
|
index: The bit to change
|
||||||
|
value: True or False to set or reset target bit
|
||||||
|
Index should be an int from 0 to 7
|
||||||
|
Value is any supported Bit-class compatible object
|
||||||
|
"""
|
||||||
# we'll take the easy way for now
|
# we'll take the easy way for now
|
||||||
l = self.list()
|
l = self.list()
|
||||||
# str->int->bool->int : accept bool, str, int, return either "0" or "1"
|
# str->int->bool->int : accept bool, str, int, return either "0" or "1"
|
||||||
|
@ -273,14 +323,33 @@ class Bits:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __ior__(self, other):
|
def __ior__(self, other):
|
||||||
|
"""
|
||||||
|
inverse or
|
||||||
|
"""
|
||||||
self = self | Bits(other)
|
self = self | Bits(other)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __contains__(self, item):
|
def __contains__(self, item):
|
||||||
|
"""
|
||||||
|
Return True if binary item is in self
|
||||||
|
item: The bits to test
|
||||||
|
Examples:
|
||||||
|
self = "00110011"
|
||||||
|
"1" in self -> True
|
||||||
|
1 in self -> True
|
||||||
|
"11" in self -> True (equiv to 3 in self, "00000011" in self)
|
||||||
|
"00010000" in self -> True (equiv to 16 in self)
|
||||||
|
"00100001" in self -> True (equiv to 33 in self, (32 + 1) in self)
|
||||||
|
In other words, returns True if bit is set
|
||||||
|
"""
|
||||||
val = Bits(item) & self
|
val = Bits(item) & self
|
||||||
return val == Bits(item)
|
return val == Bits(item)
|
||||||
|
|
||||||
def __setvalue(self, var):
|
def __setvalue(self, var):
|
||||||
|
"""
|
||||||
|
Internal function to process supported variants (object types) and
|
||||||
|
set the value of self to int(var)
|
||||||
|
"""
|
||||||
self.__value = 0
|
self.__value = 0
|
||||||
if isinstance(var, Bits):
|
if isinstance(var, Bits):
|
||||||
self.__value = int(var)
|
self.__value = int(var)
|
||||||
|
@ -296,7 +365,19 @@ class Bits:
|
||||||
" value between 0 and 255")
|
" value between 0 and 255")
|
||||||
else:
|
else:
|
||||||
self.__value = 0
|
self.__value = 0
|
||||||
|
elif isinstance(var, Bytes):
|
||||||
|
if int(var) < 256:
|
||||||
|
self.__value = int(var)
|
||||||
|
else:
|
||||||
|
raise ValueError("Bytes object must be < 256")
|
||||||
|
return list(var)
|
||||||
elif (len(var) > 0) and (len(var) <=8):
|
elif (len(var) > 0) and (len(var) <=8):
|
||||||
|
# handles: "01010101"
|
||||||
|
# ["0", "1", "0", "1", "0", "1", "0", "1"]
|
||||||
|
# [0, 1, 0, 1, 0, 1, 0, 1]
|
||||||
|
# [False, True, False, True, False, True, False, True]
|
||||||
|
# Other objects with len 1<>8 that are subscriptable
|
||||||
|
# and each subscript item can be cast to int
|
||||||
for bit in range(0, len(var)):
|
for bit in range(0, len(var)):
|
||||||
self.__value += (int(bool(int(var[bit]))) *
|
self.__value += (int(bool(int(var[bit]))) *
|
||||||
(2 ** (len(var) - 1 - bit)))
|
(2 ** (len(var) - 1 - bit)))
|
||||||
|
@ -304,6 +385,11 @@ class Bits:
|
||||||
raise TypeError("Expected object with len <= 8")
|
raise TypeError("Expected object with len <= 8")
|
||||||
|
|
||||||
def bin(self, pad=True, reverse=False):
|
def bin(self, pad=True, reverse=False):
|
||||||
|
"""
|
||||||
|
Return binary string representation of self
|
||||||
|
pad: True to include leading zeros, False to strip leading zeroes
|
||||||
|
reverse: True to return binary string representation of self as stiB.
|
||||||
|
"""
|
||||||
from math import ceil
|
from math import ceil
|
||||||
bitcount = self.__value.bit_length()
|
bitcount = self.__value.bit_length()
|
||||||
ret = ""
|
ret = ""
|
||||||
|
@ -316,44 +402,79 @@ class Bits:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def chr(self):
|
def chr(self):
|
||||||
|
"""
|
||||||
|
Return ascii character of int(self)
|
||||||
|
"""
|
||||||
return chr(self.__value)
|
return chr(self.__value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def int(self):
|
def int(self):
|
||||||
|
"""
|
||||||
|
Return int(self)
|
||||||
|
"""
|
||||||
return int(self)
|
return int(self)
|
||||||
|
|
||||||
@int.setter
|
@int.setter
|
||||||
def int(self, value):
|
def int(self, value):
|
||||||
|
"""
|
||||||
|
Set value of self
|
||||||
|
value: int(0 - 255)
|
||||||
|
"""
|
||||||
self.__setvalue(value)
|
self.__setvalue(value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def byte(self):
|
def byte(self):
|
||||||
|
"""
|
||||||
|
Return b'(self)'
|
||||||
|
"""
|
||||||
return bytes(self)
|
return bytes(self)
|
||||||
|
|
||||||
def reverse(self):
|
def reverse(self):
|
||||||
|
"""
|
||||||
|
Set Bits(self) to stiB(self)
|
||||||
|
"""
|
||||||
self.__setvalue(self.bin()[::-1])
|
self.__setvalue(self.bin()[::-1])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def msb(self):
|
def msb(self):
|
||||||
|
"""
|
||||||
|
Return most significant bit
|
||||||
|
"""
|
||||||
return self.bin()[0]
|
return self.bin()[0]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def lsb(self):
|
def lsb(self):
|
||||||
|
"""
|
||||||
|
Get least significant bit
|
||||||
|
"""
|
||||||
return self.bin()[7]
|
return self.bin()[7]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def nibble(self):
|
def nibble(self):
|
||||||
|
"""
|
||||||
|
list(bit[0:4], bit[4:8])
|
||||||
|
"""
|
||||||
return [self.bin()[:4], self.bin()[4:]]
|
return [self.bin()[:4], self.bin()[4:]]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rtl(self):
|
def rtl(self):
|
||||||
|
"""
|
||||||
|
True if stib, otherwise bits
|
||||||
|
"""
|
||||||
return self.__r_to_l
|
return self.__r_to_l
|
||||||
|
|
||||||
@rtl.setter
|
@rtl.setter
|
||||||
def rtl(self, msb_last):
|
def rtl(self, msb_last):
|
||||||
|
"""
|
||||||
|
bits|stib
|
||||||
|
01100011 becomes 11000110
|
||||||
|
"""
|
||||||
self.__r_to_l = bool(msb_last)
|
self.__r_to_l = bool(msb_last)
|
||||||
|
|
||||||
def list(self, pad=True, reverse=False):
|
def list(self, pad=True, reverse=False):
|
||||||
|
"""
|
||||||
|
Return self as list(of Bit)
|
||||||
|
"""
|
||||||
ret = []
|
ret = []
|
||||||
bits = self.bin(pad=pad, reverse=reverse)
|
bits = self.bin(pad=pad, reverse=reverse)
|
||||||
for b in bits:
|
for b in bits:
|
||||||
|
@ -367,38 +488,65 @@ class Bytes:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, var=None, byteorder="big"):
|
def __init__(self, var=None, byteorder="big"):
|
||||||
|
"""
|
||||||
|
var: a supported variant (object)
|
||||||
|
byteorder: notimplemented, mostly ignored
|
||||||
|
"""
|
||||||
self.__raw = bytearray(b'')
|
self.__raw = bytearray(b'')
|
||||||
self.__small = False
|
self.__small = False
|
||||||
|
self.__iter = None
|
||||||
|
self.__list_len = None
|
||||||
if byteorder.lower() in ["small", "little"]:
|
if byteorder.lower() in ["small", "little"]:
|
||||||
self.__small = True
|
self.__small = True
|
||||||
if var is not None:
|
if var is not None:
|
||||||
self.__raw = self.__to_bytearray(var)
|
self.__raw = self.__to_bytearray(var)
|
||||||
|
|
||||||
def __bytes__(self):
|
def __bytes__(self):
|
||||||
|
"""
|
||||||
|
Value of self in binary
|
||||||
|
"""
|
||||||
return bytes(self.__raw)
|
return bytes(self.__raw)
|
||||||
|
|
||||||
def __int__(self):
|
def __int__(self):
|
||||||
|
"""
|
||||||
|
Self, but as an intfant
|
||||||
|
"""
|
||||||
return self.int()
|
return self.int()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
"""
|
||||||
|
Represent self
|
||||||
|
"""
|
||||||
ret = f'{self.__class__.__module__}.{self.__class__.__name__}'
|
ret = f'{self.__class__.__module__}.{self.__class__.__name__}'
|
||||||
ret += f'({bytes(self)})'
|
ret += f'({bytes(self)})'
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def __index__(self):
|
def __index__(self):
|
||||||
|
"""
|
||||||
|
Return int representation of self
|
||||||
|
"""
|
||||||
return self.int()
|
return self.int()
|
||||||
|
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
|
"""
|
||||||
|
Get single byte from self as Bits object
|
||||||
|
"""
|
||||||
if not isinstance(index, int):
|
if not isinstance(index, int):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
return Bits(self.__raw[index])
|
return Bits(self.__raw[index])
|
||||||
|
|
||||||
def __setitem__(self, index, value):
|
def __setitem__(self, index, value):
|
||||||
|
"""
|
||||||
|
Change value of byte in self
|
||||||
|
"""
|
||||||
if not isinstance(index, int):
|
if not isinstance(index, int):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
self.__raw[index] = int(value)
|
self.__raw[index] = int(value)
|
||||||
|
|
||||||
def __delitem__(self, index):
|
def __delitem__(self, index):
|
||||||
|
"""
|
||||||
|
Delete (remove) byte from self
|
||||||
|
"""
|
||||||
del self.__raw[index]
|
del self.__raw[index]
|
||||||
|
|
||||||
def __test_key(self, key):
|
def __test_key(self, key):
|
||||||
|
@ -409,39 +557,78 @@ class Bytes:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __eq__(self, compare):
|
def __eq__(self, compare):
|
||||||
|
"""
|
||||||
|
int(self) == int(compare)
|
||||||
|
"""
|
||||||
return int(self) == int(compare)
|
return int(self) == int(compare)
|
||||||
|
|
||||||
def __ne__(self, compare):
|
def __ne__(self, compare):
|
||||||
|
"""
|
||||||
|
int(self) != int(compare)
|
||||||
|
"""
|
||||||
return int(self) != int(compare)
|
return int(self) != int(compare)
|
||||||
|
|
||||||
def __lt__(self, compare):
|
def __lt__(self, compare):
|
||||||
|
"""
|
||||||
|
int(self) < int(compare)
|
||||||
|
"""
|
||||||
return int(self) < int(compare)
|
return int(self) < int(compare)
|
||||||
|
|
||||||
def __le__(self, compare):
|
def __le__(self, compare):
|
||||||
|
"""
|
||||||
|
int(self) <= int(compare)
|
||||||
|
"""
|
||||||
return int(self) <= int(compare)
|
return int(self) <= int(compare)
|
||||||
|
|
||||||
def __gt__(self, compare):
|
def __gt__(self, compare):
|
||||||
|
"""
|
||||||
|
int(self) > int(compare)
|
||||||
|
"""
|
||||||
return int(self) > int(compare)
|
return int(self) > int(compare)
|
||||||
|
|
||||||
def __ge__(self, compare):
|
def __ge__(self, compare):
|
||||||
|
"""
|
||||||
|
int(self) >= int(compare)
|
||||||
|
"""
|
||||||
return int(self) >= int(compare)
|
return int(self) >= int(compare)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
|
"""
|
||||||
|
NotImplemented
|
||||||
|
"""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
|
"""
|
||||||
|
Return bool(int(self))
|
||||||
|
"""
|
||||||
return bool(int(self))
|
return bool(int(self))
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
|
"""
|
||||||
|
Return count of bytes in self
|
||||||
|
"""
|
||||||
return len(self.__raw)
|
return len(self.__raw)
|
||||||
|
|
||||||
def __get__(self, instance, owner=None):
|
def __get__(self, instance, owner=None):
|
||||||
|
"""
|
||||||
|
get(self)
|
||||||
|
"""
|
||||||
return self.__raw
|
return self.__raw
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
"""
|
||||||
|
Return binary string of self
|
||||||
|
"""
|
||||||
return self.bin()
|
return self.bin()
|
||||||
|
|
||||||
def __to_bytearray(self, var):
|
def __to_bytearray(self, var):
|
||||||
|
"""
|
||||||
|
Internal function to cast compatible objects to bytearray.
|
||||||
|
var: Any of (bytearray|int|bytes|str|Bytes|
|
||||||
|
list(of (bool|int|Bit|Bits|Bytes|bytes)))
|
||||||
|
returns: Binary representation of var as <bytearray>
|
||||||
|
"""
|
||||||
retvalue = bytearray(b'')
|
retvalue = bytearray(b'')
|
||||||
byteorder="little" if self.__small else "big"
|
byteorder="little" if self.__small else "big"
|
||||||
if isinstance(var, int):
|
if isinstance(var, int):
|
||||||
|
@ -458,7 +645,7 @@ class Bytes:
|
||||||
elif isinstance(var, bytearray):
|
elif isinstance(var, bytearray):
|
||||||
retvalue = var
|
retvalue = var
|
||||||
elif isinstance(var, Bytes):
|
elif isinstance(var, Bytes):
|
||||||
retvalue = bytearray(var)
|
retvalue = bytearray(bytes(var))
|
||||||
elif isinstance(var, list):
|
elif isinstance(var, list):
|
||||||
# test first item in list to see if it is Bit
|
# test first item in list to see if it is Bit
|
||||||
if len(var) > 0 and isinstance(var[0], (bool, Bit)):
|
if len(var) > 0 and isinstance(var[0], (bool, Bit)):
|
||||||
|
@ -498,15 +685,37 @@ class Bytes:
|
||||||
def bytes(self):
|
def bytes(self):
|
||||||
return bytes(self)
|
return bytes(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bits(self):
|
||||||
|
"""
|
||||||
|
List of Bit
|
||||||
|
"""
|
||||||
|
bitlist = []
|
||||||
|
for bite in list(self):
|
||||||
|
bitlist += list(bite)
|
||||||
|
return bitlist
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stib(self):
|
||||||
|
"""
|
||||||
|
Tsil of Bit
|
||||||
|
"""
|
||||||
|
return self.bits[::-1]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bytearray(self):
|
def bytearray(self):
|
||||||
|
"""
|
||||||
|
Copy of self as bytearray
|
||||||
|
"""
|
||||||
return bytearray(bytes(self))
|
return bytearray(bytes(self))
|
||||||
|
|
||||||
def from_int(self, i, byteorder="big"):
|
def from_int(self, i, byteorder="big"):
|
||||||
signed = False
|
signed = False
|
||||||
|
# only work with objects that can cast to int
|
||||||
|
i = int(i)
|
||||||
if i < 0:
|
if i < 0:
|
||||||
signed = True
|
signed = True
|
||||||
length = (len(self.bin(i=i, pad=True)) / 8)
|
length = int((len(self.bin(i=i, pad=True)) / 8))
|
||||||
return i.to_bytes(length=length,
|
return i.to_bytes(length=length,
|
||||||
byteorder=byteorder,
|
byteorder=byteorder,
|
||||||
signed=signed)
|
signed=signed)
|
||||||
|
|
Loading…
Reference in New Issue