gitee.com/quant1x/gox@v1.21.2/encoding/binary/struc/README.md (about) 1 [![Build Status](https://travis-ci.org/lunixbochs/struc.svg?branch=master)](https://travis-ci.org/lunixbochs/struc) [![GoDoc](https://godoc.org/github.com/lunixbochs/struc?status.svg)](https://godoc.org/github.com/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 ```