heman / binmap Goto Github PK
View Code? Open in Web Editor NEWPython base class for creating binary parsing and packing classes
License: MIT License
Python base class for creating binary parsing and packing classes
License: MIT License
Update requiremets-dev.txt and tox.ini
Here's an idea for how it could look like, inspired by dataclasses:
import binmap as bm
class SomeStruct(bm.BinMap, byteorder='<'):
small_int: int = bm.field('h', default=42)
some_padding = bm.padding(2)
some_constant: bytes = bm.constant('5s', b"Hello")
some_enum: MyEnum = bm.field('i', MyEnum.SOME_VALUE)
some_other_enum: str = bm.enum('h', {0: "East", 1: "South", 2: "West", 3: "North"})
Padding bytes could also be regular fields where the Python side type is None
, or, if you're willing to get a bit more magical, you could leave off the attribute name altogether.
Could TypeError
be used? Some ValueError
should perhaps be changed to AttributeError
.
All datatypes and multiple values like 2b
Map strings or other constants against values.
Should string and pascalstring be bytes instead of strings?
Start using Github Actions for the sake of it.
Classes that have paddings can't be presented with dataclasses.astuple
or dataclasses.asdict
Should it only look at signature or should it take _formatstring in consideration? Not taking _formatstring in consideration is more like a casting?
if somekey in somedict.keys() is more Pythonically written as if somekey in somedict
It fails fine when instantiating an object with unknow attribute but not when assigning it. Like:
class Temp(BinmapDataClass):
temp: signedchar = 0
t = Temp(hum=40)
but not
t = Temp()
t.hum = 40
Add possibility to ignore/pad data
Add possibility to hardcode values.
0 is default values, testing against something else is more robust.
Dataencoding for struct
It would be nice to make it work with enums, so that if you have things like assert Temperature(binarydata=b'...').unit is TemperatureUnit.CELCIUS.
If for example a 24 bit value is accepted in a 32 bit field it should be possible to add a validator.
Instead of exposing the binary representation with a property, how about implementing bytes, so that you could do bytes(mystruct)? Using a setter is also something I wouldn't expect, I would expect an alternative constructor like so: Temperature.frombytes(b'...')
In BinField.__set__
I should bounds check with struct.pack before updating obj.__dict__
Tests that raises exceptions should test that first, then assert that values are ok.
Create single bit true/false-attributes.
If the binary structure have
field1: something
field2...14: something
checksum: something
we could use a way to create a baseclass for that.
Have datafields with "calculations". This could be implemented as @property
in subclasses.
Could a mypy test step help to write better code?
Allow comparsion between objects. Equal/not equal is only sane.
Like checksums or length or such.
docs/
Certain protocols, like HTTP and the one used by Redis, terminate successive fields using \r\n
, and to me there isn't a clean way to do this using binmap.
(I think the closest approximation is to repeatedly append n-sized padding fields, like the test shown here). The approximation resembles:
class AdvancedPad(binmap.BinmapDataclass):
temp: b_types.unsignedchar = 0
_pad1: b_types.pad = binmap.padding(2)
humidity: b_types.unsignedchar = 0
_pad2: b_types.pad = binmap.padding(3)
_pad3: b_types.pad = binmap.padding(1)
but in my opinion it doesn't scale well to really big classes/structs. Ergonomically-speaking, I think the following would be a fun way to implement the \r\n
terminator within client code:
# `\r\n` uses the bytes 0x0A and 0x0D
@binmap.postfix(b"\x0A\x0D", btype=b_types.???)
class HttpResponse(binmap.BinmapDataclass):
status_line: StatusLine
# The first `binmap.padding(2)` group might ordinarily go here,
# but since padding serves a different utility from a terminator
# group, I believe a `binmap.postfix` decorator would inject
# private fields of type `btype`.
response_header_fields: ...
but some other fun cases pop up when we look at what would be needed for StatusLine
. Naively, we might try:
class StatusLine(binmap.BinmapDataclass):
protocol: b_types.string = b"HTTP/1.1"
_p1: b_types.pad = binmap.padding(1) # Space character for alignment
response_code: b_types.unsignedchar = 200
_p2: b_types.pad = binmap.padding(1) # Space character for alignment
status: b_types.string = b"OK"
_terminator: b_types.??? = b"\x0A\x0D"
however this shouldn't deserialize correctly if we want the keep the whitespace between protocol
, response_code
, and status
.
Rather than postfix
, I think cases like these warrant a different decorator -- one which selectively appends fields at deliberate positions. In other words, we'd need something that hides the labors for reading/writing space chars after protocol
and response_code
. I'm imagining something like:
@binmap.insert(b" ", btype=b_types.unsigned_char, after=["protocol", "response_code"])
class StatusLine(binmap.BinmapDataclass):
protocol: b_types.string = b"HTTP/1.1"
response_code: b_types.unsignedchar = 200
status: b_types.string = b"OK"
_terminator: b_types.??? = b"\x0A\x0D"
What are your thoughts, @HeMan ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.