|
|
|
@ -1,33 +1,218 @@
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
"""
|
|
|
|
|
============================
|
|
|
|
|
Binary manipulation classes
|
|
|
|
|
============================
|
|
|
|
|
|
|
|
|
|
Provides classes that assist in managing, comparing, transforming and working
|
|
|
|
|
with binary data in general.
|
|
|
|
|
|
|
|
|
|
-----------------
|
|
|
|
|
Provided Classes
|
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
|
|
Bit
|
|
|
|
|
===
|
|
|
|
|
The Bit is the smallest representation of binary data and represents True or
|
|
|
|
|
False. This class provides methods to perform binary comparisons and
|
|
|
|
|
conversions between different types that can be used to represent a single
|
|
|
|
|
binary value.
|
|
|
|
|
|
|
|
|
|
Byte
|
|
|
|
|
====
|
|
|
|
|
A Byte is the representation of 8 Bits. The Byte class provides methods to
|
|
|
|
|
compare a single binary Byte to other data types. The Class also provides
|
|
|
|
|
binary math functions and allows getting and setting the state of individual
|
|
|
|
|
Bits.
|
|
|
|
|
|
|
|
|
|
Bytes
|
|
|
|
|
=====
|
|
|
|
|
The Bytes class allows an arbitrary amount of binary data to be represented.
|
|
|
|
|
The Bytes class provides access to each byte using the Byte class, which
|
|
|
|
|
further allows all the methods to be used on the binary data provided by the
|
|
|
|
|
Byte and Bit classes. Bytes can be compared and converted between several
|
|
|
|
|
different data types.
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
class Bit:
|
|
|
|
|
"""
|
|
|
|
|
Provide a flexible bit representation.
|
|
|
|
|
====
|
|
|
|
|
Bit
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
A single binary bit representation of True or False
|
|
|
|
|
|
|
|
|
|
A Bit object can be compared and converted to int, str, bool and other Bit
|
|
|
|
|
objects. The Bit class is backed by a single bool variable. This backing
|
|
|
|
|
bool object is converted as necessary to provide conversions and
|
|
|
|
|
comparisons with other data types. Keep this in mind as converting an
|
|
|
|
|
object to Bit and then attempting to convert back to the original object
|
|
|
|
|
may not yield the exact same value.
|
|
|
|
|
|
|
|
|
|
In the case of comparisons, the object being compared is cast as a Bit
|
|
|
|
|
object, and the two Bit objects are then compared with each other and the
|
|
|
|
|
result of the comparison is returned.
|
|
|
|
|
|
|
|
|
|
----------------
|
|
|
|
|
Type Conversion
|
|
|
|
|
----------------
|
|
|
|
|
The objects that can be converted to and from a Bit include *bool*, *int*,
|
|
|
|
|
*str* and other *Bit* objects.
|
|
|
|
|
|
|
|
|
|
Convert *bool* to *Bit*:
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
/>/>/> a_bit = Bit(True)
|
|
|
|
|
/>/>/> a_bit
|
|
|
|
|
Bit(1)
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
Convert *Bit* to *bool*:
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
/>/>/> a_bool = bool(Bit(True))
|
|
|
|
|
/>/>/> a_bool
|
|
|
|
|
True
|
|
|
|
|
/>/>/> type(a_bool)
|
|
|
|
|
<class 'bool'>
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
Convert *int* to *Bit*:
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
/>/>/> unset_bit = Bit(0)
|
|
|
|
|
/>/>/> unset_bit
|
|
|
|
|
Bit(0)
|
|
|
|
|
/>/>/> set_bit = Bit(1)
|
|
|
|
|
/>/>/> set_bit
|
|
|
|
|
Bit(1)
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
Convert *Bit* to *int*:
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
/>/>/> my_int = int(Bit(1))
|
|
|
|
|
/>/>/> my_int
|
|
|
|
|
1
|
|
|
|
|
/>/>/> type(my_int)
|
|
|
|
|
<class 'int'>
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
.. note:: The only values allowed for *int* are **0** and **1**
|
|
|
|
|
|
|
|
|
|
Convert *str* to *Bit*:
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
/>/>/> unset_bit = Bit("0")
|
|
|
|
|
/>/>/> unset_bit
|
|
|
|
|
Bit(0)
|
|
|
|
|
/>/>/> set_bit = Bit("1")
|
|
|
|
|
/>/>/> set_bit
|
|
|
|
|
Bit(1)
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
Convert *Bit* to *str*:
|
|
|
|
|
.. code-block: python
|
|
|
|
|
|
|
|
|
|
/>/>/> my_str = str(Bit(False))
|
|
|
|
|
/>/>/> my_str
|
|
|
|
|
'0'
|
|
|
|
|
/>/>/> type(my_str)
|
|
|
|
|
<class 'str'>
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
.. note:: The only *str* characters allowed are a single **0** or **1**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
------------
|
|
|
|
|
Comparisons
|
|
|
|
|
------------
|
|
|
|
|
A Bit object can be compared to any object which can be cast to a Bit
|
|
|
|
|
|
|
|
|
|
.. code-block: python
|
|
|
|
|
|
|
|
|
|
/>/>/> 0 == Bit(False) == Bit("0") == Bit(0) == False
|
|
|
|
|
True
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
.. note:: Comparing an object with a value that cannot be cast to Bit will
|
|
|
|
|
return a ValueError.
|
|
|
|
|
|
|
|
|
|
-----------------
|
|
|
|
|
Rich Comparisons
|
|
|
|
|
-----------------
|
|
|
|
|
Bit objects also support "rich comparisons". For example:
|
|
|
|
|
|
|
|
|
|
.. code-block: python
|
|
|
|
|
|
|
|
|
|
/>/>/> Bit(False) < 1
|
|
|
|
|
True
|
|
|
|
|
/>/>/> Bit(True) <= 1
|
|
|
|
|
True
|
|
|
|
|
/>/>/> Bit(False) <= "1"
|
|
|
|
|
True
|
|
|
|
|
/>/>/> Bit(False) != True
|
|
|
|
|
True
|
|
|
|
|
/>/>/> Bit(True) >= False
|
|
|
|
|
False
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--------
|
|
|
|
|
Methods
|
|
|
|
|
--------
|
|
|
|
|
The action method `toggle` is provided for convenience.
|
|
|
|
|
|
|
|
|
|
.. code-block: python
|
|
|
|
|
|
|
|
|
|
/>/>/> Bit(False).toggle()
|
|
|
|
|
Bit(1)
|
|
|
|
|
/>/>/> Bit(True).toggle() == False
|
|
|
|
|
True
|
|
|
|
|
/>/>/> int(Bit(False).toggle())
|
|
|
|
|
1
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
The `set` and `unset` methods are also provided to explicitely set the
|
|
|
|
|
value of Bit.
|
|
|
|
|
|
|
|
|
|
.. code-block: python
|
|
|
|
|
|
|
|
|
|
/>/>/> a_bit = Bit(0)
|
|
|
|
|
/>/>/> a_bit
|
|
|
|
|
Bit(0)
|
|
|
|
|
/>/>/> a_bit.set()
|
|
|
|
|
/>/>/> a_bit
|
|
|
|
|
Bit(1)
|
|
|
|
|
/>/>/> a_bit.unset()
|
|
|
|
|
/>/>/> a_bit
|
|
|
|
|
Bit(0)
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-----------
|
|
|
|
|
Properties
|
|
|
|
|
-----------
|
|
|
|
|
The `lie` property returns the opposite value of Bit as a *bool*. Unlike
|
|
|
|
|
the `toggle` method, `lie` does not change the value of the Bit.
|
|
|
|
|
|
|
|
|
|
Extended description of function.
|
|
|
|
|
.. code-block: python
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
|
|
|
|
var : bool | int | str | Bit
|
|
|
|
|
Any of the supported objects which can be converted to a Bit object.
|
|
|
|
|
bool: True or False
|
|
|
|
|
int: 0 = False, anything else = True
|
|
|
|
|
str: "0" = False, anything else = True
|
|
|
|
|
BIT: Bit = Bit
|
|
|
|
|
/>/>/> Bit(1).lie
|
|
|
|
|
False
|
|
|
|
|
/>/>/>
|
|
|
|
|
|
|
|
|
|
Returns
|
|
|
|
|
-------
|
|
|
|
|
Bit
|
|
|
|
|
A binary representation of True or False with additional useful
|
|
|
|
|
features.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
int: 0 = False, 1 = True
|
|
|
|
|
str: "0" = False, "1" = True
|
|
|
|
|
Bit: Bit = Bit
|
|
|
|
|
"""
|
|
|
|
|
if not isinstance(var, (bool, int, str, Bit)):
|
|
|
|
@ -45,25 +230,22 @@ class Bit:
|
|
|
|
|
self.__bit = var
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
"""
|
|
|
|
|
Return "0" or "1"
|
|
|
|
|
"""
|
|
|
|
|
"""Return '0' or '1'"""
|
|
|
|
|
return str(int(self.__bit))
|
|
|
|
|
|
|
|
|
|
def __int__(self):
|
|
|
|
|
"""Return 0 or 1"""
|
|
|
|
|
return int(self.__bit)
|
|
|
|
|
|
|
|
|
|
def __bool__(self):
|
|
|
|
|
"""Returns True or False"""
|
|
|
|
|
return self.__bit
|
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
|
return f'{self.__class__.__name__}({int(self.__bit)})'
|
|
|
|
|
|
|
|
|
|
def __eq__(self, compare):
|
|
|
|
|
"""
|
|
|
|
|
compare (self) to any supported object
|
|
|
|
|
"""
|
|
|
|
|
# Massage compare to bool
|
|
|
|
|
"""compare (self) to any supported object"""
|
|
|
|
|
return bool(self) == bool(Bit(compare))
|
|
|
|
|
|
|
|
|
|
def __ne__(self, compare):
|
|
|
|
@ -85,22 +267,24 @@ class Bit:
|
|
|
|
|
return self.__bit
|
|
|
|
|
|
|
|
|
|
def __hash__(self):
|
|
|
|
|
"""
|
|
|
|
|
Not very useful, but provided nonetheless
|
|
|
|
|
"""
|
|
|
|
|
"""Not very useful, but provided nonetheless"""
|
|
|
|
|
return hash(self.__bit)
|
|
|
|
|
|
|
|
|
|
def toggle(self):
|
|
|
|
|
"""
|
|
|
|
|
(self) = Not (Self)
|
|
|
|
|
"""
|
|
|
|
|
"""Change the state of (self) to Not (self)"""
|
|
|
|
|
self.__bit = not self.__bit
|
|
|
|
|
|
|
|
|
|
def set(self):
|
|
|
|
|
"""Set Bit to True"""
|
|
|
|
|
self.__bit = True
|
|
|
|
|
|
|
|
|
|
def unset(self):
|
|
|
|
|
"""Set Bit to False"""
|
|
|
|
|
self.__bit = False
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def lie(self):
|
|
|
|
|
"""
|
|
|
|
|
Return the opposite of bit, without changing the state of (self)
|
|
|
|
|
"""
|
|
|
|
|
"""Return the opposite of bit, without changing the state of (self)"""
|
|
|
|
|
return not self.__bit
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|