[plum] Tutorial: Byte Breakdown Summaries¶
dump property¶
plum
instances offer a dump
property to help visualize
the resulting byte structure, the associated value, and the method
of accessing the value. The property returns a dump object that
supports string conversion to facilitate logging and debugging as
well as supports calls to print the summary to the console.
For example:
>>> from plum.structure import Member, Structure
>>> from plum.int.little import UInt8, UInt16
>>>
>>> class MyStruct(Structure):
... byte: int = Member(cls=UInt8)
... word: int = Member(cls=UInt16)
...
>>> mystruct = MyStruct(byte=1, word=2)
>>> mystruct.dump()
+--------+-------------+-------+-------+----------+
| Offset | Access | Value | Bytes | Type |
+--------+-------------+-------+-------+----------+
| | | | | MyStruct |
| 0 | [0] (.byte) | 1 | 01 | UInt8 |
| 1 | [1] (.word) | 2 | 02 00 | UInt16 |
+--------+-------------+-------+-------+----------+
The “Offset” column shows the byte offset in overall byte structure for each structure member. The “Access” column shows the syntax to use to access the value. The “Value” column shows the representation of the member’s unpacked bytes. The “Memory” column contains hexidecimal representation of the member’s bytes.
When an exception occurs while packing or unpacking bytes, the exception message includes a dump to show the successful progress made and the point at which the failure occurred. In the following example, the structure requires one more byte than what was provided:
>>> from plum import unpack
>>>
>>> x = unpack(MyStruct, b'\x02\x01')
Traceback (most recent call last):
...
plum._exceptions.UnpackError:
<BLANKLINE>
+--------+-------------+----------------------+-------+----------+
| Offset | Access | Value | Bytes | Type |
+--------+-------------+----------------------+-------+----------+
| | | | | MyStruct |
| 0 | [0] (.byte) | 2 | 02 | UInt8 |
| 1 | [1] (.word) | <insufficient bytes> | 01 | UInt16 |
+--------+-------------+----------------------+-------+----------+
<BLANKLINE>
InsufficientMemoryError occurred during unpack operation:
<BLANKLINE>
1 too few bytes to unpack UInt16 (2 needed, only 1 available)
Pack/Unpack Exceptions¶
When pack or unpack operations fail for any reason, the exception message always includes the byte breakdown summary showing the successful progress made before the problem occurred to facilitate debugging. In the following example, the bytes to unpack contains one unexpected extra byte:
>>> from plum import unpack
>>> from plum.int.little import UInt16
>>>
>>> unpack(UInt16, b'\x01\x00\x99')
Traceback (most recent call last):
...
plum._exceptions.UnpackError:
<BLANKLINE>
+--------+----------------+-------+--------+
| Offset | Value | Bytes | Type |
+--------+----------------+-------+--------+
| 0 | 1 | 01 00 | UInt16 |
+--------+----------------+-------+--------+
| 2 | <excess bytes> | 99 | |
+--------+----------------+-------+--------+
<BLANKLINE>
ExcessMemoryError occurred during unpack operation:
<BLANKLINE>
1 unconsumed bytes
Pack/Unpack Dump Alternatives¶
This package offers identical alternatives to every pack and unpack function
and method variation. The alternative produces a byte breakdown summary dump
while performing the operation and supply the dump in the return value. For
example, the unpack_and_dump()
function mirrors the unpack()
function except that it includes the dump in the return:
>>> from plum import unpack, unpack_and_dump
>>> from plum.int.little import UInt8
>>>
>>> unpack((UInt8, UInt8), b'\x01\x02')
(1, 2)
>>> value, dump = unpack_and_dump((UInt8, UInt8), b'\x01\x02')
>>> value
(1, 2)
>>> dump()
+--------+--------+-------+-------+-------+
| Offset | Access | Value | Bytes | Type |
+--------+--------+-------+-------+-------+
| 0 | [0] | 1 | 01 | UInt8 |
| 1 | [1] | 2 | 02 | UInt8 |
+--------+--------+-------+-------+-------+
Besides simplifying your code, using these alternatives may improve performance a bit since when used as a separate operation, the dump mechanics perform a pack.
Function/Method Alternative pack pack_and_dump pack_into pack_into_and_dummp unpack unpack_and_dump unpack_from unpack_from_and_dump
Tip
For speed critical operations, don’t use the dump property or the dump function and method alternatives since they add substantial speed costs.