{"id":20785388,"url":"https://github.com/o-murphy/pystruct-go","last_synced_at":"2025-06-23T00:34:17.638Z","repository":{"id":240567339,"uuid":"802645453","full_name":"o-murphy/pystruct-go","owner":"o-murphy","description":"Go lang implementation of python's struct module","archived":false,"fork":false,"pushed_at":"2024-05-21T16:48:11.000Z","size":81,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-11T23:32:57.506Z","etag":null,"topics":["cstruct","ctypes","go","golang","gomod","gomodule","marshalling","struct"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/o-murphy/pystruct-go","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/o-murphy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-18T21:38:05.000Z","updated_at":"2024-05-21T16:48:14.000Z","dependencies_parsed_at":"2024-06-19T15:09:19.453Z","dependency_job_id":null,"html_url":"https://github.com/o-murphy/pystruct-go","commit_stats":null,"previous_names":["o-murphy/go-cstruct","o-murphy/pystruct-go"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/o-murphy/pystruct-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-murphy%2Fpystruct-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-murphy%2Fpystruct-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-murphy%2Fpystruct-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-murphy%2Fpystruct-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/o-murphy","download_url":"https://codeload.github.com/o-murphy/pystruct-go/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-murphy%2Fpystruct-go/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261390222,"owners_count":23151505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cstruct","ctypes","go","golang","gomod","gomodule","marshalling","struct"],"created_at":"2024-11-17T14:45:21.135Z","updated_at":"2025-06-23T00:34:12.623Z","avatar_url":"https://github.com/o-murphy.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PyStruct\n## Go lang implementation of python's struct module\n\n#### Interpret bytes as packed binary data\n\n\n\u003e [!TIP] \n\u003e If you can't find something in `README.md` you can search references in \n\u003e *[Python's struct documentation](https://docs.python.org/3/library/struct.html)*\n\n\u003e [!NOTE] \n\u003e Some functionality not yet implemented, [details there](#not-yet-implemented)\n\n\u003e [!NOTE]\n\u003e Tested only with small values\n\n### Contents\n* [Installation](#installation)\n* [Usage](#usage)\n\t* [Example](#example)\n\t* [Byte Order, Size, and Alignment](#byte-order-size-and-alignment)\n\t* [Format characters](#format-characters)\n\t* [Functions](#functions)\n\t\t* [func CalcSize](#func-calcsize)\n\t\t* [func Pack](#func-pack)\n\t\t* [func PackInto](#func-packinto)\n\t\t* [func Unpack](#func-unpack)\n\t\t* [func UnpackFrom](#func-unpackfrom)\n\t\t* [func IterUnpack](#func-iterunpack)\n\t* [Types](#types)\n\t\t* [Type PyStruct](#type-struct-1)\n\t\t\t* [func CalcSize](#func-calcsize-1)\n\t\t\t* [func Pack](#func-pack-1)\n\t\t\t* [func PackInto](#func-packinto-1)\n\t\t\t* [func Unpack](#func-unpack-1)\n\t\t\t* [func UnpackFrom](#func-unpackfrom-1)\n\t\t\t* [func IterUnpack](#func-iterunpack-1)\n\n\n## Installation\n\n``` bash\ngo get github.com/o-murphy/pystruct-go\n```\n\n## Usage\n### Example\n```go\npackage main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\n\tpystruct \"github.com/o-murphy/pystruct-go\"\n)\n\nfunc main() {\n\n\t// unpack\n\tbyteArray := []byte{97, 98, 99, 100, 101, 102, 103}\n\tintf, err := pystruct.Unpack(`\u003c3sf`, byteArray)\n\tif err == nil {\n\t\tfmt.Println(intf...)\n\t}\n\n\t// pack\n\tbyteArray2, err := pystruct.Pack(`\u003c3sf`, intf...)\n\tif err == nil {\n\t\tfmt.Println(byteArray2)\n\t}\n\n\tif bytes.Equal(byteArray, byteArray2) {\n\t\tfmt.Println(\"Equal\")\n\t}\n\n\t// or use struct\n\ts := pystruct.NewStruct(`\u003c3sf`)\n\tbyteArray, err := s.Pack(intf...)\n\tintf, err := s.Unpack(byteArray)\n\n}\n```\n\n### Byte Order, Size, and Alignment\n\u003cdetails\u003e \n  \u003csummary\u003eDetails\u003c/summary\u003e\n   By default, C types are represented in the machine’s native format and byte order, and properly aligned by skipping pad bytes if necessary (according to the rules used by the C compiler). This behavior is chosen so that the bytes of a packed struct correspond exactly to the memory layout of the corresponding C struct. Whether to use native byte ordering and padding or standard formats depends on the application.\n   \n   Alternatively, the first character of the format string can be used to indicate the byte order, size and alignment of the packed data, according to the following table: \n\u003c/details\u003e\n\n|Character  |Byte order            |Size    |Alignment |\n|:---------:|----------------------|--------|----------|\n|@          |native                |native  |native    |\n|=          |native                |standard|none      |\n|\u003c          |little-endian         |standard|none      |\n|\u003e          |big-endian            |standard|none      |\n|!          |network (= big-endian)|standard|none      |\n\n\u003e [!TIP] \n\u003e If the first character is not one of these, '@' is assumed.\n\n\u003e [!NOTE]\n\u003e Note The number 1023 (0x3ff in hexadecimal) has the following byte representations:\n\u003e ```\n\u003e 03 ff in big-endian (\u003e)\n\u003e ff 03 in little-endian (\u003c)\n\u003e ```\n\u003e [More info there...](https://docs.python.org/3/library/struct.html#struct-alignment)\n\n\n### Format Characters\n\u003cdetails\u003e \n  \u003csummary\u003eDetails\u003c/summary\u003e\n\tFormat characters have the following meaning; the conversion between C and Python values should be obvious given their types. The ‘Standard size’ column refers to the size of the packed value in bytes when using standard size; that is, when the format string starts with one of '\u003c', '\u003e', '!' or '='. When using native size, the size of the packed value is platform-dependent. \n\u003c/details\u003e\n\n\u003e [!NOTE]\n\u003e [More info there...](https://docs.python.org/3/library/struct.html#format-characters)\n\n| Format | C Type              | Go Type           | Python Type       | Standard Size |\n| :----: | ------------------- | ----------------- | ----------------- | ------------- |\n|   c    | char                | byte              | bytes of length 1 | 1             |\n|   b    | signed char         | int8              | integer           | 1             |\n|   B    | unsigned char       | uint8             | integer           | 1             |\n|   ?    | _Bool               | bool              | bool              | 1             |\n|   h    | short               | int16             | integer           | 2             |\n|   H    | unsigned short      | uint16            | integer           | 2             |\n|   i    | int                 | int32             | integer           | 4             |\n|   I    | unsigned int        | uint32            | integer           | 4             |\n|   l    | long                | int32             | integer           | 4             |\n|   L    | unsigned long       | uint32            | integer           | 4             |\n|   q    | long long           | int64             | integer           | 8             |\n|   Q    | unsigned long long  | uint64            | integer           | 8             |\n|   f    | float               | float32 (float64) | float             | 4 (8)         |\n|   d    | double              | float64 (float32) | float             | 8 (4)         |\n|   s    | char[]              | string            | bytes             | Variable      |\n|   x    | pad byte            | [N/A**](#na)      | no value          |               |\n|   n    | ssize_t             | [N/A**](#na)      | integer           |               |\n|   N    | size_t              | [N/A**](#na)      | integer           |               |\n|   e    | [float16](#float16) | [N/A**](#na)      | float             |  2             |\n|   p    | char[]              | [N/A**](#na)      | bytes             |               |\n|   P    | void*               | [N/A**](#na)      | integer           |               |\n\n### Functions\n#### func CalcSize\n```go\nfunc CalcSize(format string) (int, error)\n```\nReturn the size of the struct\n(and hence of the bytes object produced by pack(format, ...))\ncorresponding to the format string format\n\n\u003e ```go\n\u003e size, err := pystruct.CalcSize(format)\n\u003e if err == nil {\n\u003e\tfmt.Println(size)\n\u003e }\n\u003e ```\n\n#### func Pack\n```go\nfunc Pack(format string, intf []interface{}) ([]byte, error)\n```\nReturn a bytes object containing the values v1, v2, … packed according to the format string format.\nThe arguments must match the values required by the format exactly.\n\n\u003e ```go\n\u003e intf := []interface{}{\"abc\", 1.01}\n\u003e byteArray, err := pystruct.Pack(`\u003c3sf`, intf)\n\u003e if err == nil {\n\u003e\tfmt.Println(byteArray2)\n\u003e }\n\u003e ```\n\n\n#### func PackInto\n```go\nfunc PackInto(format string, buffer []byte, offset int, intf ...interface{}) ([]byte, error)\n```\nPack the values v1, v2, … according to the format string format\nand write the packed bytes into the writable buffer\nstarting at position offset. Note that offset is a required argument.\n\n\u003e ```go\n\u003e intf := []interface{}{\"abc\", 1.01}\n\u003e buffer := []byte{0xff, 0xff, 0xff, 0xff}\n\u003e byteArray, err := pystruct.PackInto(`\u003c3sf`, buffer, 3, intf)\n\u003e if err == nil {\n\u003e\tfmt.Println(byteArray)\n\u003e }\n\u003e ```\n\n#### func Unpack\n```go\nfunc Unpack(format string, buffer []byte) ([]interface{}, error)\n```\nUnpack from the buffer buffer (presumably packed by Pack(format, ...))\naccording to the format string format. The result is an []interface{} even if it contains exactly one item.\nThe buffer’s size in bytes must match the size required by the format, as reflected by CalcSize().\n\n\u003e ```go\n\u003e byteArray := []byte{97, 98, 99, 100, 101, 102, 103}\n\u003e intf, err := pystruct.Unpack(`\u003c3sf`, byteArray)\n\u003e if err == nil {\n\u003e\tfmt.Println(intf...)\n\u003e }\n\u003e ```\n\n#### func UnpackFrom\n```go\nfunc UnpackFrom(format string, buffer []byte, offset int) ([]interface{}, error)\n```\nUnpack from buffer starting at position offset, according to the format string format.\nThe result is an []interface{} even if it contains exactly one item.\nThe buffer’s size in bytes, starting at position offset,\nmust be at least the size required by the format, as reflected by CalcSize().\n\n\u003e ```go\n\u003e byteArray := []byte{0, 0, 0, 97, 98, 99, 100, 101, 102, 103}\n\u003e intf, err := pystruct.UnpackFrom(`\u003c3sf`, byteArray, 3)\n\u003e if err == nil {\n\u003e\tfmt.Println(intf...)\n\u003e }\n\u003e ```\n\n#### func IterUnpack\n```go\nfunc IterUnpack(format string, buffer []byte) (\u003c-chan interface{}, \u003c-chan error)\n```\nIteratively unpack from the buffer buffer according to the format string format.\nThis function returns an iterator which will read equally sized chunks from the buffer until all its contents have been consumed.\nThe buffer’s size in bytes must be a multiple of the size required by the format, as reflected by CalcSize()\n\n\u003c!-- // iterator, errs := pystruct.IterUnpack(format, byteArray)\n// for i, value := 0, \u003c-iterator; errs == nil; i, value = i+1, \u003c-iterator {\n// \tfmt.Println(i, value)\n// } --\u003e\n\n\u003e ```go\n\u003e format := `\u003c3si`\n\u003e byteArray := []byte{97, 98, 99, 100, 101, 102, 103}\n\u003e iterator, errs := pystruct.IterUnpack(format, byteArray)\n\u003e\n\u003e i := 0\n\u003e for value := range iterator {\n\u003e \tfmt.Println(i, value)\n\u003e   i++\n\u003e }\n\u003e ```\n\n### Types\n#### type PyStruct\n```go\ntype PyStruct struct {\n\tformat string\n}\n```\nPyStruct(fmt) --\u003e compiled PyStruct object\n\n##### func NewStruct\n```go\nNewStruct(format string) (PyStruct, error)\n```\nNewStruct(fmt) --\u003e compiled PyStruct object\nMethods bellow this just binds for same named functions\n\n##### func CalcSize\n([⬆️CalcSize](#func-pack))\n```go\nfunc (s *PyStruct) CalcSize() (int, error)\n```\n\n##### func Pack\n([⬆️Pack](#func-pack))\n```go\nfunc (s *PyStruct) Pack(intf ...interface{}) ([]byte, error)\n```\n\n##### func PackInto\n([⬆️PackInto](#func-packinto))\n```go\nfunc (s *PyStruct) PackInto(buffer []byte, offset int, intf ...interface{}) ([]byte, error) \n```\n\n##### func Unpack\n([⬆️Unpack](#func-unpack))\n```go\nfunc (s *PyStruct) Unpack(buffer []byte) ([]interface{}, error)\n```\n\n##### func UnpackFrom\n([⬆️UnpackFrom](#func-unpackfrom))\n```go\nfunc (s *PyStruct) UnpackFrom(buffer []byte, offset int) ([]interface{}, error) \n```\n\n##### func IterUnpack\n([⬆️IterUnpack](#func-iterunpack))\n```go\nfunc (s *PyStruct) IterUnpack(format string, buffer []byte) (\u003c-chan interface{}, \u003c-chan error)\n```\n\n### Not yet implemented\n##### N/A\n* `p` char[] - Pascal string\n* `P` void*\n* `x` PadByte\n* `n` ssize_t\n* `N` size_t\n##### Float16\n* `e` Float16 - *(IEEE 754 binary16 half precision float)*\n\n### RISK NOTICE\n\u003e [!IMPORTANT]\n\u003e THE CODE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-murphy%2Fpystruct-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fo-murphy%2Fpystruct-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-murphy%2Fpystruct-go/lists"}