binstruct: github.com/ghostiam/binstruct Index | Examples | Files

package binstruct

import "github.com/ghostiam/binstruct"

Code:

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))

}

Code:

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))

}

Code:

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]}

Code:

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]}

Code:

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): ([]uint8) (len=2 cap=2) {
 00000000  00 01                                             |..|
}
Read(want: 2|actual: 2): ([]uint8) (len=2 cap=2) {
 00000000  00 02                                             |..|
}
Read(want: 2|actual: 2): ([]uint8) (len=2 cap=2) {
 00000000  00 03                                             |..|
}
Read(want: 2|actual: 2): ([]uint8) (len=2 cap=2) {
 00000000  00 04                                             |..|
}
{Arr:[1 2 3 4]}

Code:

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

Examples

Package Files

binstruct.go errors.go reader.go tag.go unmarshal.go

Variables

var (
    // ErrNegativeCount is returned when an attempt is made to read a negative number of bytes
    ErrNegativeCount = errors.New("binstruct: negative count")
)

func IsEOF Uses

func IsEOF(err error) bool

IsEOF checks that the error is EOF

func IsUnexpectedEOF Uses

func IsUnexpectedEOF(err error) bool

IsUnexpectedEOF checks that the error is Unexpected EOF

func Unmarshal Uses

func Unmarshal(data []byte, order binary.ByteOrder, v interface{}) error

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 Uses

func UnmarshalBE(data []byte, v interface{}) error

UnmarshalBE parses the binary data with big-endian byte order and stores the result in the value pointed to by v.

func UnmarshalLE Uses

func UnmarshalLE(data []byte, v interface{}) error

UnmarshalLE parses the binary data with little-endian byte order and stores the result in the value pointed to by v.

type Decoder Uses

type Decoder struct {
    // contains filtered or unexported fields
}

A Decoder reads and decodes binary values from an input stream.

func NewDecoder Uses

func NewDecoder(r io.ReadSeeker, order binary.ByteOrder) *Decoder

NewDecoder returns a new decoder that reads from r with byte order.

func (*Decoder) Decode Uses

func (dec *Decoder) Decode(v interface{}) error

Decode reads the binary-encoded value from its input and stores it in the value pointed to by v.

func (*Decoder) SetDebug Uses

func (dec *Decoder) SetDebug(debug bool)

SetDebug if set true, all read bytes and offsets will be displayed.

type InvalidUnmarshalError Uses

type InvalidUnmarshalError struct {
    Type reflect.Type
}

An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. (The argument to Unmarshal must be a non-nil pointer.)

func (*InvalidUnmarshalError) Error Uses

func (e *InvalidUnmarshalError) Error() string

type Reader Uses

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)

    // 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)

    // 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
}

Reader is the interface that wraps the binstruct reader methods.

func NewReader Uses

func NewReader(r io.ReadSeeker, order binary.ByteOrder, debug bool) Reader

NewReader returns a new reader that reads from r with byte order. If debug set true, all read bytes and offsets will be displayed.

func NewReaderFromBytes Uses

func NewReaderFromBytes(data []byte, order binary.ByteOrder, debug bool) Reader

NewReaderFromBytes returns a new reader that reads from data with byte order. If debug set true, all read bytes and offsets will be displayed.

Package binstruct imports 12 packages (graph). Updated 2020-02-09. Refresh now. Tools for package owners.