Documentation ¶
Overview ¶
Example (DecodeCustom) ¶
package main import ( "bytes" "encoding/binary" "fmt" "log" "github.com/davecgh/go-spew/spew" "github.com/lkarlslund/binstruct" ) type custom struct { ID int16 _ [1]byte TypeLen int16 Type string `bin:"len:TypeLen"` B []byte `bin:"len:3"` } type data struct { StrLen int `bin:"len:2,offset:1"` Str string `bin:"len:StrLen"` Int int32 `bin:"len:2"` ArrLen uint16 ISlice []int `bin:"len:ArrLen,[len:4]"` IArr [2]int32 SSlice []string `bin:"len:ArrLen,[StringFunc]"` Map map[int]string `bin:"MapFunc"` Skip []byte `bin:"-"` Custom custom } func (d *data) StringFunc(r binstruct.Reader) (string, error) { _, _, err := r.ReadBytes(1) if err != nil { return "", err } lenStr, err := r.ReadUint16() if err != nil { return "", err } _, str, err := r.ReadBytes(int(lenStr)) if err != nil { return "", err } return string(str), nil } func (d *data) MapFunc(r binstruct.Reader) error { s := make(map[int]string) for i := 0; i < 2; i++ { _, _, err := r.ReadBytes(1) if err != nil { return err } lenStr, err := r.ReadUint16() if err != nil { return err } _, str, err := r.ReadBytes(int(lenStr)) if err != nil { return err } s[i] = string(str) } d.Map = s return nil } func main() { var b = []byte{ 's', 0x00, 0x05, 'h', 'e', 'l', 'l', 'o', // string // Int 0x00, 0x0A, // ArrLen 0x00, 0x02, // ISlice 0x00, 0x00, 0x00, 0x11, // [0]int 0x00, 0x00, 0x00, 0x22, // [1]int // IArr 0x00, 0x00, 0x00, 0x33, // [0]int 0x00, 0x00, 0x00, 0x44, // [1]int // SSlice 's', 0x00, 0x02, 'h', 'i', // [0]string 's', 0x00, 0x03, 'y', 'a', 'y', // [1]string // Map 's', 0x00, 0x02, 'h', 'i', // [0]string 's', 0x00, 0x03, 'y', 'a', 'y', // [1]string // Custom 0x00, 0xff, // int 0xff, // skip 0x00, 0x04, // str len 't', 'e', 's', 't', // string 'h', 'i', '!', // bytes } var actual data decoder := binstruct.NewDecoder(bytes.NewReader(b), binary.BigEndian) err := decoder.Decode(&actual) if err != nil { log.Fatal(err) } spewCfg := spew.NewDefaultConfig() spewCfg.SortKeys = true fmt.Print(spewCfg.Sdump(actual)) }
Output: (binstruct_test.data) { StrLen: (int) 5, Str: (string) (len=5) "hello", Int: (int32) 10, ArrLen: (uint16) 2, ISlice: ([]int) (len=2 cap=2) { (int) 17, (int) 34 }, IArr: ([2]int32) (len=2 cap=2) { (int32) 51, (int32) 68 }, SSlice: ([]string) (len=2 cap=2) { (string) (len=2) "hi", (string) (len=3) "yay" }, Map: (map[int]string) (len=2) { (int) 0: (string) (len=2) "hi", (int) 1: (string) (len=3) "yay" }, Skip: ([]uint8) <nil>, Custom: (binstruct_test.custom) { ID: (int16) 255, _: ([1]uint8) (len=1 cap=1) { 00000000 00 |.| }, TypeLen: (int16) 4, Type: (string) (len=4) "test", B: ([]uint8) (len=3 cap=4) { 00000000 68 69 21 |hi!| } } }
Example (DecoderDataWithNullTerminatedString) ¶
package main import ( "bytes" "encoding/binary" "fmt" "github.com/davecgh/go-spew/spew" "github.com/lkarlslund/binstruct" ) type dataWithNullTerminatedString struct { ID int32 Type string `bin:"NullTerminatedString"` OtherID int32 } func (*dataWithNullTerminatedString) NullTerminatedString(r binstruct.Reader) (string, error) { var b []byte for { readByte, err := r.ReadByte() if binstruct.IsEOF(err) { break } if err != nil { return "", err } if readByte == 0x00 { break } b = append(b, readByte) } return string(b), nil } func main() { b := []byte{ // ID 0x00, 0x00, 0x00, 0x05, // Type as null-terminated string 't', 'e', 's', 't', 0x00, // OtherID 0xff, 0xff, 0xff, 0xf0, } var actual dataWithNullTerminatedString decoder := binstruct.NewDecoder(bytes.NewReader(b), binary.BigEndian) err := decoder.Decode(&actual) if err != nil { panic(err) } fmt.Print(spew.Sdump(actual)) }
Output: (binstruct_test.dataWithNullTerminatedString) { ID: (int32) 5, Type: (string) (len=4) "test", OtherID: (int32) -16 }
Example (ReadmeFromBytes) ¶
package main import ( "fmt" "log" "github.com/lkarlslund/binstruct" ) func main() { data := []byte{ 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, } type dataStruct struct { Arr []int16 `bin:"len:4"` } var actual dataStruct err := binstruct.UnmarshalBE(data, &actual) // UnmarshalLE() or Unmarshal() if err != nil { log.Fatal(err) } fmt.Printf("%+v", actual) }
Output: {Arr:[1 2 3 4]}
Example (ReadmeFromIOReadSeeker) ¶
package main import ( "encoding/binary" "fmt" "log" "os" "github.com/lkarlslund/binstruct" ) func main() { file, err := os.Open("testdata/file.bin") if err != nil { log.Fatal(err) } type dataStruct struct { Arr []int16 `bin:"len:4"` } var actual dataStruct decoder := binstruct.NewDecoder(file, binary.BigEndian) // decoder.SetDebug(true) // you can enable the output of bytes read for debugging err = decoder.Decode(&actual) if err != nil { log.Fatal(err) } fmt.Printf("%+v", actual) }
Output: {Arr:[1 2 3 4]}
Example (ReadmeFromIOReadSeekerWithDebuging) ¶
package main import ( "encoding/binary" "fmt" "log" "os" "github.com/lkarlslund/binstruct" ) func main() { file, err := os.Open("testdata/file.bin") if err != nil { log.Fatal(err) } type dataStruct struct { Arr []int16 `bin:"len:4"` } var actual dataStruct decoder := binstruct.NewDecoder(file, binary.BigEndian) decoder.SetDebug(true) // you can enable the output of bytes read for debugging err = decoder.Decode(&actual) if err != nil { log.Fatal(err) } fmt.Printf("%+v", actual) }
Output: Read(want: 2|actual: 2): 00000000 00 01 |..| Read(want: 2|actual: 2): 00000000 00 02 |..| Read(want: 2|actual: 2): 00000000 00 03 |..| Read(want: 2|actual: 2): 00000000 00 04 |..| {Arr:[1 2 3 4]}
Example (ReadmeReader) ¶
package main import ( "encoding/binary" "fmt" "log" "github.com/lkarlslund/binstruct" ) func main() { data := []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F} reader := binstruct.NewReaderFromBytes(data, binary.BigEndian, false) i16, err := reader.ReadInt16() if err != nil { log.Fatal(err) } fmt.Println(i16) i32, err := reader.ReadInt32() if err != nil { log.Fatal(err) } fmt.Println(i32) b, err := reader.Peek(4) if err != nil { log.Fatal(err) } fmt.Printf("Peek bytes: %#v\n", b) an, b, err := reader.ReadBytes(4) if err != nil { log.Fatal(err) } fmt.Printf("Read %d bytes: %#v\n", an, b) other, err := reader.ReadAll() if err != nil { log.Fatal(err) } fmt.Printf("Read all: %#v\n", other) }
Output: 258 50595078 Peek bytes: []byte{0x7, 0x8, 0x9, 0xa} Read 4 bytes: []byte{0x7, 0x8, 0x9, 0xa} Read all: []byte{0xb, 0xc, 0xd, 0xe, 0xf}
Index ¶
- Variables
- func IsEOF(err error) booldeprecated
- func IsUnexpectedEOF(err error) booldeprecated
- func Unmarshal(data []byte, order binary.ByteOrder, v interface{}) error
- func UnmarshalBE(data []byte, v interface{}) error
- func UnmarshalLE(data []byte, v interface{}) error
- type BinaryDecoder
- type Decoder
- type InvalidUnmarshalError
- type Reader
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNegativeCount is returned when an attempt is made to read a negative number of bytes ErrNegativeCount = errors.New("binstruct: negative count") )
Functions ¶
func IsUnexpectedEOF
deprecated
func Unmarshal ¶
Unmarshal parses the binary data with byte order and stores the result in the value pointed to by v. If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.
func UnmarshalBE ¶
UnmarshalBE parses the binary data with big-endian byte order and stores the result in the value pointed to by v.
func UnmarshalLE ¶
UnmarshalLE parses the binary data with little-endian byte order and stores the result in the value pointed to by v.
Types ¶
type BinaryDecoder ¶
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
A Decoder reads and decodes binary values from an input stream.
func NewDecoder ¶
func NewDecoder(r io.ReadSeeker, order binary.ByteOrder) *Decoder
NewDecoder returns a new decoder that reads from r with byte order.
type InvalidUnmarshalError ¶
An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. (The argument to Unmarshal must be a non-nil pointer.)
func (*InvalidUnmarshalError) Error ¶
func (e *InvalidUnmarshalError) Error() string
type Reader ¶
type Reader interface { io.ReadSeeker // Peek returns the next n bytes without advancing the reader. Peek(n int) ([]byte, error) // ReadBytes reads up to n bytes. It returns the number of bytes // read, bytes and any error encountered. ReadBytes(n int) (an int, b []byte, err error) // ReadAll reads until an error or EOF and returns the data it read. ReadAll() ([]byte, error) // ReadByte read and return one byte ReadByte() (byte, error) // ReadBool read one byte and return boolean value ReadBool() (bool, error) // ReadUint8 read one byte and return uint8 value ReadUint8() (uint8, error) // ReadUint16 read two bytes and return uint16 value ReadUint16() (uint16, error) // ReadUint32 read four bytes and return uint32 value ReadUint32() (uint32, error) // ReadUint64 read eight bytes and return uint64 value ReadUint64() (uint64, error) // ReadUintX read X bytes and return uint64 value ReadUintX(x int) (uint64, error) // ReadInt8 read one byte and return int8 value ReadInt8() (int8, error) // ReadInt16 read two bytes and return int16 value ReadInt16() (int16, error) // ReadInt32 read four bytes and return int32 value ReadInt32() (int32, error) // ReadInt64 read eight bytes and return int64 value ReadInt64() (int64, error) // ReadIntX read X bytes and return int64 value ReadIntX(x int) (int64, error) // ReadFloat32 read four bytes and return float32 value ReadFloat32() (float32, error) // ReadFloat64 read eight bytes and return float64 value ReadFloat64() (float64, error) // Unmarshal parses the binary data and stores the result // in the value pointed to by v. Unmarshal(v interface{}) error // WithOrder changes the byte order for the new Reader WithOrder(order binary.ByteOrder) Reader }
Reader is the interface that wraps the binstruct reader methods.