initial commit
[govpp.git] / vendor / github.com / lunixbochs / struc / README.md
1 [![Build Status](https://travis-ci.org/lunixbochs/struc.svg?branch=master)](https://travis-ci.org/lunixbochs/struc)
2
3 struc
4 ====
5
6 Struc exists to pack and unpack C-style structures from bytes, which is useful for binary files and network protocols. It could be considered an alternative to `encoding/binary`, which requires massive boilerplate for some similar operations.
7
8 Take a look at an [example comparing `struc` and `encoding/binary`](https://bochs.info/p/cxvm9)
9
10 Struc considers usability first. That said, it does cache reflection data and aims to be competitive with `encoding/binary` struct packing in every way, including performance.
11
12 Example struct
13 ----
14
15 ```Go
16 type Example struct {
17     Var   int `struc:"int32,sizeof=Str"`
18     Str   string
19     Weird []byte `struc:"[8]int64"`
20     Var   []int `struc:"[]int32,little"`
21 }
22 ```
23
24 Struct tag format
25 ----
26
27  - ```Var []int `struc:"[]int32,little,sizeof=StringField"` ``` will pack Var as a slice of little-endian int32, and link it as the size of `StringField`.
28  - `sizeof=`: Indicates this field is a number used to track the length of a another field. `sizeof` fields are automatically updated on `Pack()` based on the current length of the tracked field, and are used to size the target field during `Unpack()`.
29  - Bare values will be parsed as type and endianness.
30
31 Endian formats
32 ----
33
34  - `big` (default)
35  - `little`
36
37 Recognized types
38 ----
39
40  - `pad` - this type ignores field contents and is backed by a `[length]byte` containing nulls
41  - `bool`
42  - `byte`
43  - `int8`, `uint8`
44  - `int16`, `uint16`
45  - `int32`, `uint32`
46  - `int64`, `uint64`
47  - `float32`
48  - `float64`
49
50 Types can be indicated as arrays/slices using `[]` syntax. Example: `[]int64`, `[8]int32`.
51
52 Bare slice types (those with no `[size]`) must have a linked `Sizeof` field.
53
54 Private fields are ignored when packing and unpacking.
55
56 Example code
57 ----
58
59 ```Go
60 package main
61
62 import (
63     "bytes"
64     "github.com/lunixbochs/struc"
65 )
66
67 type Example struct {
68     A int `struc:"big"`
69
70     // B will be encoded/decoded as a 16-bit int (a "short")
71     // but is stored as a native int in the struct
72     B int `struc:"int16"`
73
74     // the sizeof key links a buffer's size to any int field
75     Size int `struc:"int8,little,sizeof=Str"`
76     Str  string
77
78     // you can get freaky if you want
79     Str2 string `struc:"[5]int64"`
80 }
81
82 func main() {
83     var buf bytes.Buffer
84     t := &Example{1, 2, 0, "test", "test2"}
85     err := struc.Pack(&buf, t)
86     o := &Example{}
87     err = struc.Unpack(&buf, o)
88 }
89 ```
90
91 Benchmark
92 ----
93
94 `BenchmarkEncode` uses struc. `Stdlib` benchmarks use equivalent `encoding/binary` code. `Manual` encodes without any reflection, and should be considered an upper bound on performance (which generated code based on struc definitions should be able to achieve).
95
96 ```
97 BenchmarkEncode        1000000   1265 ns/op
98 BenchmarkStdlibEncode  1000000   1855 ns/op
99 BenchmarkManualEncode  5000000    284 ns/op
100 BenchmarkDecode        1000000   1259 ns/op
101 BenchmarkStdlibDecode  1000000   1656 ns/op
102 BenchmarkManualDecode  20000000  89.0 ns/op
103 ```