Skip to main content

Simple library for de/serializing binary data

Project description

binpi

binpi aims to provide a simple interface for serializing and deserializing binary file formats.

Usage:

import binpi

class Data:
    ...

class FileHeader:
    prop1 = binpi.Int()
    prop2 = binpi.Short()
    prop3 = binpi.Byte()
    is_compressed = binpi.Boolean()
    float_prop = binpi.Float()
    some_data = binpi.ByteArray(size="prop1")
    other_data = binpi.List(Data, size="prop3")
    sub_struct = binpi.WrapType(Data)
    children_count = binpi.Int()
    children = binpi.List(binpi.RecursiveType(), size="children_count")
    
# deserializing    
header_data = binpi.deserialize(FileHeader, binpi.FileReader("./some_path"), endianness=binpi.LITTLE_ENDIAN)

# modify
header_data.prop2 = 200

# serializing 
writer = binpi.serialize(header_data, binpi.FileWriter("./another_path"), endianness=binpi.LITTLE_ENDIAN)

For more complex examples, check ./examples/

How to install:

pip install binpi

Supported Types:

  • Int, UInt, Short, UShort, Byte, UByte, Float, Double
  • IntEnumType
  • List, String, ByteArray
  • Boolean
  • RecursiveType (for cases where the structure contains list of substructures of the same type, check the advanced_structure example)
  • WrapType (for subtypes, check the simple_image_archive_format example)
  • All the types above support LE/BE

Comparing with other (de)serializing libraries

  • pickle - should be used for completely different use-cases than binpi, which is just simple deserializing of python objects, without having to care about its structure.
  • struct - anything binpi does can be implemented using struct, but binpi provides simpler interface for defining data structure, for the cost of performance.
  • origami - origami might be a better choice for (de)serializing fixed size data, but it doesn't provide (de)serializing of dynamically sized data, out of the box.
  • bstruct - same as origami
  • construct - probably the most comparable library to binpi, has even more feature, but instead of binpi, the data structures and output is represented using dictionaries

Interface

Serializing

def serialize(
    value,           # value to be serialized
    writer: Writer,  # the output writer
    first=None,      # first field to serialize
    last=None        # last field to serialize
) -> None: ...

class Writer(Protocol):
    """ writer can be anything that implements method write_bytes """
    def write_bytes(self, data: bytes) -> None: ...

binpi contains FileWriter and BufferWriter

Deserializing

def deserialize(
    class_: type,    # type of the target object 
    reader: Reader,  # the input reader
    first=None,      # first field to serialize
    last=None        # last field to serialize
) -> None: ...

class Reader(Protocol):
    """ reader can be anything that implements method read_bytes """
    def read_bytes(self, n: int) -> bytes: ...

binpi contains FileReader and BufferReader

Extending with custom types

To create your own custom (de)serializable type, you have to just create a new child class of SerializableType that implements load_from_bytes and write_from_value

import typing, binpi, struct

class CustomDoubledInt(binpi.SerializableType):
    def load_from_bytes(self, deserializer: binpi.Deserializer, instance, *args, **kwargs):
        return struct.unpack("<i", deserializer.reader.read_bytes(4))[0] * 2

    def write_from_value(self, serializer: binpi.Serializer, value, parent_instance, *args, **kwargs):
        serializer.writer.write_bytes(struct.pack("<i", value // 2))

""" In case we want to have functional typechecking """
CustomDoubleInt: typing.Callable[..., int]

TODO:

  • Tests
  • Performance benchmarks

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

binpi-0.1.20.tar.gz (9.0 kB view details)

Uploaded Source

Built Distribution

binpi-0.1.20-py3-none-any.whl (11.0 kB view details)

Uploaded Python 3

File details

Details for the file binpi-0.1.20.tar.gz.

File metadata

  • Download URL: binpi-0.1.20.tar.gz
  • Upload date:
  • Size: 9.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for binpi-0.1.20.tar.gz
Algorithm Hash digest
SHA256 5be53c4663b65cad13226c2b538b804cc814454a292f4fc932c8aa123fea84b9
MD5 4337a6b40bc726594f47a49ab4005974
BLAKE2b-256 5282f340cd9689e2d6d63582a9b708de5f8eb4e760c86cee1de3ac094521bd7e

See more details on using hashes here.

File details

Details for the file binpi-0.1.20-py3-none-any.whl.

File metadata

  • Download URL: binpi-0.1.20-py3-none-any.whl
  • Upload date:
  • Size: 11.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for binpi-0.1.20-py3-none-any.whl
Algorithm Hash digest
SHA256 7f76fdf08ea26411fc951a88df754a5c2138c63a285cb4f54c8d223bb4916586
MD5 de6b6df6c425c338c7ae58b8dd33e773
BLAKE2b-256 17663f27576e2a9e986e5040c53c07496216bf05345639a091685411736c2da8

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page