struc

package module
v0.0.0-...-784aaeb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2020 License: MIT Imports: 11 Imported by: 1,728

README

Build Status GoDoc

struc

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.

Take a look at an example comparing struc and encoding/binary

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.

Example struct

type Example struct {
    Var   int `struc:"int32,sizeof=Str"`
    Str   string
    Weird []byte `struc:"[8]int64"`
    Var   []int `struc:"[]int32,little"`
}

Struct tag format

  • 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.
  • 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().
  • Bare values will be parsed as type and endianness.

Endian formats

  • big (default)
  • little

Recognized types

  • pad - this type ignores field contents and is backed by a [length]byte containing nulls
  • bool
  • byte
  • int8, uint8
  • int16, uint16
  • int32, uint32
  • int64, uint64
  • float32
  • float64

Types can be indicated as arrays/slices using [] syntax. Example: []int64, [8]int32.

Bare slice types (those with no [size]) must have a linked Sizeof field.

Private fields are ignored when packing and unpacking.

Example code

package main

import (
    "bytes"
    "github.com/lunixbochs/struc"
)

type Example struct {
    A int `struc:"big"`

    // B will be encoded/decoded as a 16-bit int (a "short")
    // but is stored as a native int in the struct
    B int `struc:"int16"`

    // the sizeof key links a buffer's size to any int field
    Size int `struc:"int8,little,sizeof=Str"`
    Str  string

    // you can get freaky if you want
    Str2 string `struc:"[5]int64"`
}

func main() {
    var buf bytes.Buffer
    t := &Example{1, 2, 0, "test", "test2"}
    err := struc.Pack(&buf, t)
    o := &Example{}
    err = struc.Unpack(&buf, o)
}

Benchmark

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

BenchmarkEncode        1000000   1265 ns/op
BenchmarkStdlibEncode  1000000   1855 ns/op
BenchmarkManualEncode  5000000    284 ns/op
BenchmarkDecode        1000000   1259 ns/op
BenchmarkStdlibDecode  1000000   1656 ns/op
BenchmarkManualDecode  20000000  89.0 ns/op

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Pack

func Pack(w io.Writer, data interface{}) error

func PackWithOptions

func PackWithOptions(w io.Writer, data interface{}, options *Options) error

func PackWithOrder

func PackWithOrder(w io.Writer, data interface{}, order binary.ByteOrder) error

Deprecated. Use PackWithOptions.

func Sizeof

func Sizeof(data interface{}) (int, error)

func SizeofWithOptions

func SizeofWithOptions(data interface{}, options *Options) (int, error)

func Unpack

func Unpack(r io.Reader, data interface{}) error

func UnpackWithOptions

func UnpackWithOptions(r io.Reader, data interface{}, options *Options) error

func UnpackWithOrder

func UnpackWithOrder(r io.Reader, data interface{}, order binary.ByteOrder) error

Deprecated. Use UnpackWithOptions.

Types

type Custom

type Custom interface {
	Pack(p []byte, opt *Options) (int, error)
	Unpack(r io.Reader, length int, opt *Options) error
	Size(opt *Options) int
	String() string
}

type Field

type Field struct {
	Name  string
	Ptr   bool
	Index int
	Type  Type

	Array    bool
	Slice    bool
	Len      int
	Order    binary.ByteOrder
	Sizeof   []int
	Sizefrom []int
	Fields   Fields
	// contains filtered or unexported fields
}

func (*Field) Pack

func (f *Field) Pack(buf []byte, val reflect.Value, length int, options *Options) (int, error)

func (*Field) Size

func (f *Field) Size(val reflect.Value, options *Options) int

func (*Field) String

func (f *Field) String() string

func (*Field) Unpack

func (f *Field) Unpack(buf []byte, val reflect.Value, length int, options *Options) error

type Fields

type Fields []*Field

func (Fields) Pack

func (f Fields) Pack(buf []byte, val reflect.Value, options *Options) (int, error)

func (Fields) SetByteOrder

func (f Fields) SetByteOrder(order binary.ByteOrder)

func (Fields) Sizeof

func (f Fields) Sizeof(val reflect.Value, options *Options) int

func (Fields) String

func (f Fields) String() string

func (Fields) Unpack

func (f Fields) Unpack(r io.Reader, val reflect.Value, options *Options) error

type Float16

type Float16 float64

func (*Float16) Pack

func (f *Float16) Pack(p []byte, opt *Options) (int, error)

func (*Float16) Size

func (f *Float16) Size(opt *Options) int

func (*Float16) String

func (f *Float16) String() string

func (*Float16) Unpack

func (f *Float16) Unpack(r io.Reader, length int, opt *Options) error

type Off_t

type Off_t int64

type Options

type Options struct {
	ByteAlign int
	PtrSize   int
	Order     binary.ByteOrder
}

func (*Options) Validate

func (o *Options) Validate() error

type Packer

type Packer interface {
	Pack(buf []byte, val reflect.Value, options *Options) (int, error)
	Unpack(r io.Reader, val reflect.Value, options *Options) error
	Sizeof(val reflect.Value, options *Options) int
	String() string
}

type Size_t

type Size_t uint64

type Type

type Type int
const (
	Invalid Type = iota
	Pad
	Bool
	Int
	Int8
	Uint8
	Int16
	Uint16
	Int32
	Uint32
	Int64
	Uint64
	Float32
	Float64
	String
	Struct
	Ptr

	SizeType
	OffType
	CustomType
)

func (Type) Resolve

func (t Type) Resolve(options *Options) Type

func (Type) Size

func (t Type) Size() int

func (Type) String

func (t Type) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL