Documentation
¶
Overview ¶
Example (DecodeCustom) ¶
package main
import (
"bytes"
"encoding/binary"
"fmt"
"log"
"github.com/davecgh/go-spew/spew"
"github.com/ghostiam/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=3) { 00000000 68 69 21 |hi!| } } }
Example (DecoderDataWithNullTerminatedString) ¶
package main
import (
"bytes"
"encoding/binary"
"fmt"
"github.com/davecgh/go-spew/spew"
"github.com/ghostiam/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/ghostiam/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/ghostiam/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/ghostiam/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/ghostiam/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 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 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.