# pycstruct
[![AppVeyor](https://ci.appveyor.com/api/projects/status/github/midstar/pycstruct?svg=true)](https://ci.appveyor.com/api/projects/status/github/midstar/pycstruct)
[![Coverage Status](https://coveralls.io/repos/github/midstar/pycstruct/badge.svg?branch=HEAD)](https://coveralls.io/github/midstar/pycstruct?branch=HEAD)
[![Documentation](https://readthedocs.org/projects/pycstruct/badge/?version=latest)](https://pycstruct.readthedocs.io/en/latest/?badge=latest)
pycstruct is a python library for converting binary data to and from ordinary
python dictionaries or specific instance objects.
Data is defined similar to what is done in C language structs, unions,
bitfields and enums.
Typical usage of this library is read/write binary files or binary data
transmitted over a network.
Following complex C types are supported:
- Structs
- Unions
- Bitfields
- Enums
These types may consist of any traditional data types (integer, unsigned integer,
boolean and float) between 1 to 8 bytes large, arrays (lists), and strings (ASCII/UTF-8).
Structs, unions, bitfields and enums can be embedded inside other structs/unions
in any level.
Individual elements can be stored / read in any byte order and alignment.
pycstruct also supports parsing of existing C language source code to
automatically generate the pycstruct definitions / instances.
Checkout the full documentation [here](https://pycstruct.readthedocs.io/en/latest/).
## Installation
Simply install the package using pip:
python3 -m pip install pycstruct
## Example
Following C has a structure (person) with a set of elements
that are written to a binary file.
```c
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#pragma pack(1) // To secure no padding is added in struct
struct person
{
char name[50];
unsigned int age;
float height;
bool is_male;
unsigned int nbr_of_children;
unsigned int child_ages[10];
};
void main(void) {
struct person p;
memset(&p, 0, sizeof(struct person));
strcpy(p.name, "Foo Bar");
p.age = 42;
p.height = 1.75; // m
p.is_male = true;
p.nbr_of_children = 2;
p.child_ages[0] = 7;
p.child_ages[1] = 9;
FILE *f = fopen("simple_example.dat", "w");
fwrite(&p, sizeof(struct person), 1, f);
fclose(f);
}
```
To read the binary file using pycstruct following code
required.
```python
import pycstruct
person = pycstruct.StructDef()
person.add('utf-8', 'name', length=50)
person.add('uint32', 'age')
person.add('float32','height')
person.add('bool8', 'is_male')
person.add('uint32', 'nbr_of_children')
person.add('uint32', 'child_ages', length=10)
with open('simple_example.dat', 'rb') as f:
inbytes = f.read()
# Dictionary representation
result = person.deserialize(inbytes)
print('Dictionary object:')
print(str(result))
# Alternative, Instance representation
instance = person.instance(inbytes)
print('\nInstance object:')
print(f'name: {instance.name}')
print(f'nbr_of_children: {instance.nbr_of_children}')
print(f'child_ages[1]: {instance.child_ages[1]}')
```
The produced output will be::
{'name': 'Foo Bar', 'is_male': True, 'nbr_of_children': 2,
'age': 42, 'child_ages': [7, 9, 0, 0, 0, 0, 0, 0, 0, 0],
'height': 1.75}
Instance object:
name: Foo Bar
nbr_of_children: 2
child_ages[1]: 9
To write a binary file from python using the same structure
using pycstruct following code is required.
```python
import pycstruct
person = pycstruct.StructDef()
person.add('utf-8', 'name', length=50)
person.add('uint32', 'age')
person.add('float32','height')
person.add('bool8', 'is_male')
person.add('uint32', 'nbr_of_children')
person.add('uint32', 'child_ages', length=10)
# Dictionary representation
mrGreen = {}
mrGreen['name'] = "MR Green"
mrGreen['age'] = 50
mrGreen['height'] = 1.93
mrGreen['is_male'] = True
mrGreen['nbr_of_children'] = 3
mrGreen['child_ages'] = [13,24,12]
buffer = person.serialize(mrGreen)
# Alternative, Instance representation
mrGreen = person.instance()
mrGreen.name = "MR Green"
mrGreen.age = 50
mrGreen.height = 1.93
mrGreen.is_male = True
mrGreen.nbr_of_children = 3
mrGreen.child_ages[0] = 13
mrGreen.child_ages[1] = 24
mrGreen.child_ages[2] = 12
buffer = bytes(mrGreen)
# Write to file
f = open('simple_example_mr_green.dat','wb')
f.write(buffer)
f.close()
```
## Parsing source files
pycstruct also supports parsing C source code defined in external
files or defined in strings.
Assume the C code listed in the first example is named
simple_example.c. Then you could parse the source
code instead of manually creating the definitions:
```python
import pycstruct
definitions = pycstruct.parse_file('simple_example.c')
with open('simple_example.dat', 'rb') as f:
inbytes = f.read()
# Dictionary representation
result = definitions['person'].deserialize(inbytes)
print(str(result))
# Alternative, Instance representation
instance = definitions['person'].instance(inbytes)
```
The produced output will be the same as in the first example (the dictionary).
## Full documentation
Checkout the full documentation [here](https://pycstruct.readthedocs.io/en/latest/).
## Author and license
This application is written by Joel Midstjärna and is licensed under the MIT License.
Raw data
{
"_id": null,
"home_page": "http://github.com/midstar/pycstruct",
"name": "pycstruct",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "struct, enum, bitfield, binary, protocol, dict, dictionary",
"author": "Joel Midstj\u00e4rna",
"author_email": "joel.midstjarna@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/b3/79/2ef54f0c3c0fef35fcf1e963436ff88a7706e40a578a8b60dfdef4ba4ae5/pycstruct-0.12.2.tar.gz",
"platform": null,
"description": "# pycstruct\r\n\r\n[![AppVeyor](https://ci.appveyor.com/api/projects/status/github/midstar/pycstruct?svg=true)](https://ci.appveyor.com/api/projects/status/github/midstar/pycstruct)\r\n[![Coverage Status](https://coveralls.io/repos/github/midstar/pycstruct/badge.svg?branch=HEAD)](https://coveralls.io/github/midstar/pycstruct?branch=HEAD)\r\n[![Documentation](https://readthedocs.org/projects/pycstruct/badge/?version=latest)](https://pycstruct.readthedocs.io/en/latest/?badge=latest)\r\n\r\npycstruct is a python library for converting binary data to and from ordinary\r\npython dictionaries or specific instance objects.\r\n\r\nData is defined similar to what is done in C language structs, unions,\r\nbitfields and enums.\r\n\r\nTypical usage of this library is read/write binary files or binary data\r\ntransmitted over a network.\r\n\r\nFollowing complex C types are supported:\r\n\r\n- Structs\r\n- Unions\r\n- Bitfields\r\n- Enums\r\n\r\nThese types may consist of any traditional data types (integer, unsigned integer, \r\nboolean and float) between 1 to 8 bytes large, arrays (lists), and strings (ASCII/UTF-8).\r\n\r\nStructs, unions, bitfields and enums can be embedded inside other structs/unions\r\nin any level. \r\n\r\nIndividual elements can be stored / read in any byte order and alignment.\r\n\r\npycstruct also supports parsing of existing C language source code to\r\nautomatically generate the pycstruct definitions / instances.\r\n\r\nCheckout the full documentation [here](https://pycstruct.readthedocs.io/en/latest/).\r\n\r\n## Installation\r\n\r\nSimply install the package using pip:\r\n\r\n python3 -m pip install pycstruct\r\n\r\n## Example\r\n\r\nFollowing C has a structure (person) with a set of elements\r\nthat are written to a binary file.\r\n\r\n```c\r\n#include <stdio.h>\r\n#include <stdbool.h>\r\n#include <string.h>\r\n\r\n#pragma pack(1) // To secure no padding is added in struct\r\n\r\nstruct person \r\n{ \r\n char name[50];\r\n unsigned int age;\r\n float height;\r\n bool is_male;\r\n unsigned int nbr_of_children;\r\n unsigned int child_ages[10];\r\n};\r\n\r\n\r\nvoid main(void) {\r\n struct person p;\r\n memset(&p, 0, sizeof(struct person));\r\n\r\n strcpy(p.name, \"Foo Bar\");\r\n p.age = 42;\r\n p.height = 1.75; // m\r\n p.is_male = true;\r\n p.nbr_of_children = 2;\r\n p.child_ages[0] = 7;\r\n p.child_ages[1] = 9;\r\n\r\n FILE *f = fopen(\"simple_example.dat\", \"w\");\r\n fwrite(&p, sizeof(struct person), 1, f);\r\n fclose(f);\r\n}\r\n```\r\n\r\nTo read the binary file using pycstruct following code \r\nrequired.\r\n\r\n```python\r\nimport pycstruct\r\n\r\nperson = pycstruct.StructDef()\r\nperson.add('utf-8', 'name', length=50)\r\nperson.add('uint32', 'age')\r\nperson.add('float32','height')\r\nperson.add('bool8', 'is_male')\r\nperson.add('uint32', 'nbr_of_children')\r\nperson.add('uint32', 'child_ages', length=10)\r\n\r\nwith open('simple_example.dat', 'rb') as f:\r\n inbytes = f.read()\r\n\r\n# Dictionary representation\r\nresult = person.deserialize(inbytes)\r\nprint('Dictionary object:')\r\nprint(str(result))\r\n\r\n# Alternative, Instance representation\r\ninstance = person.instance(inbytes)\r\nprint('\\nInstance object:')\r\nprint(f'name: {instance.name}')\r\nprint(f'nbr_of_children: {instance.nbr_of_children}')\r\nprint(f'child_ages[1]: {instance.child_ages[1]}')\r\n```\r\n\r\nThe produced output will be::\r\n\r\n {'name': 'Foo Bar', 'is_male': True, 'nbr_of_children': 2, \r\n 'age': 42, 'child_ages': [7, 9, 0, 0, 0, 0, 0, 0, 0, 0], \r\n 'height': 1.75}\r\n\r\n Instance object:\r\n name: Foo Bar\r\n nbr_of_children: 2\r\n child_ages[1]: 9\r\n\r\nTo write a binary file from python using the same structure\r\nusing pycstruct following code is required.\r\n\r\n```python\r\nimport pycstruct\r\n\r\nperson = pycstruct.StructDef()\r\nperson.add('utf-8', 'name', length=50)\r\nperson.add('uint32', 'age')\r\nperson.add('float32','height')\r\nperson.add('bool8', 'is_male')\r\nperson.add('uint32', 'nbr_of_children')\r\nperson.add('uint32', 'child_ages', length=10)\r\n\r\n# Dictionary representation\r\nmrGreen = {}\r\nmrGreen['name'] = \"MR Green\"\r\nmrGreen['age'] = 50\r\nmrGreen['height'] = 1.93\r\nmrGreen['is_male'] = True\r\nmrGreen['nbr_of_children'] = 3\r\nmrGreen['child_ages'] = [13,24,12]\r\nbuffer = person.serialize(mrGreen)\r\n\r\n# Alternative, Instance representation\r\nmrGreen = person.instance()\r\nmrGreen.name = \"MR Green\"\r\nmrGreen.age = 50\r\nmrGreen.height = 1.93\r\nmrGreen.is_male = True\r\nmrGreen.nbr_of_children = 3\r\nmrGreen.child_ages[0] = 13\r\nmrGreen.child_ages[1] = 24\r\nmrGreen.child_ages[2] = 12\r\nbuffer = bytes(mrGreen)\r\n\r\n# Write to file\r\nf = open('simple_example_mr_green.dat','wb')\r\nf.write(buffer)\r\nf.close()\r\n```\r\n\r\n## Parsing source files\r\n\r\npycstruct also supports parsing C source code defined in external\r\nfiles or defined in strings.\r\n\r\nAssume the C code listed in the first example is named\r\nsimple_example.c. Then you could parse the source\r\ncode instead of manually creating the definitions:\r\n\r\n```python\r\nimport pycstruct\r\n\r\ndefinitions = pycstruct.parse_file('simple_example.c')\r\n\r\nwith open('simple_example.dat', 'rb') as f:\r\n inbytes = f.read()\r\n\r\n# Dictionary representation\r\nresult = definitions['person'].deserialize(inbytes)\r\nprint(str(result))\r\n\r\n# Alternative, Instance representation\r\ninstance = definitions['person'].instance(inbytes)\r\n```\r\n\r\nThe produced output will be the same as in the first example (the dictionary).\r\n\r\n## Full documentation\r\n\r\nCheckout the full documentation [here](https://pycstruct.readthedocs.io/en/latest/).\r\n\r\n## Author and license\r\n\r\nThis application is written by Joel Midstj\u00c3\u00a4rna and is licensed under the MIT License.\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Binary data handling in Python using dictionaries",
"version": "0.12.2",
"project_urls": {
"Bug Tracker": "https://github.com/midstar/pycstruct/issues",
"Documentation": "https://pycstruct.readthedocs.io/en/latest/",
"Homepage": "http://github.com/midstar/pycstruct",
"Source Code": "https://github.com/midstar/pycstruct"
},
"split_keywords": [
"struct",
" enum",
" bitfield",
" binary",
" protocol",
" dict",
" dictionary"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "ea4b1834449e4c9eb44e3ed3671d51e79d7e2f04b3f8e87dcff7cf4f8f9c3943",
"md5": "a9371cf64141a7da2634c2172be8558f",
"sha256": "ddde9816981f1b74cdf3dfa2732eaf2872644f9d7d3cf8794bcf152394274970"
},
"downloads": -1,
"filename": "pycstruct-0.12.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a9371cf64141a7da2634c2172be8558f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 23497,
"upload_time": "2024-03-24T20:55:42",
"upload_time_iso_8601": "2024-03-24T20:55:42.972131Z",
"url": "https://files.pythonhosted.org/packages/ea/4b/1834449e4c9eb44e3ed3671d51e79d7e2f04b3f8e87dcff7cf4f8f9c3943/pycstruct-0.12.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b3792ef54f0c3c0fef35fcf1e963436ff88a7706e40a578a8b60dfdef4ba4ae5",
"md5": "5989e9295872eea89483875df7f34e1b",
"sha256": "273fc23892b9855d41fcafafa511c5f7d69c7dc54eb683bba5b161ea38305114"
},
"downloads": -1,
"filename": "pycstruct-0.12.2.tar.gz",
"has_sig": false,
"md5_digest": "5989e9295872eea89483875df7f34e1b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 35063,
"upload_time": "2024-03-24T20:55:44",
"upload_time_iso_8601": "2024-03-24T20:55:44.845612Z",
"url": "https://files.pythonhosted.org/packages/b3/79/2ef54f0c3c0fef35fcf1e963436ff88a7706e40a578a8b60dfdef4ba4ae5/pycstruct-0.12.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-03-24 20:55:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "midstar",
"github_project": "pycstruct",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"appveyor": true,
"tox": true,
"lcname": "pycstruct"
}