bindec

package module
v0.0.0-...-bc9598e Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2019 License: MIT Imports: 14 Imported by: 0

README

bindec Build Status Go Report Card

bindec generates encoders and decoders to encode and decode binary representations of types. Encoders and decoders are code-generated, thus generating code tailored specifically for your type, making encoding and decoding really fast.

Install
go get github.com/erizocosmico/bindec/cmd/...
Usage
bindec -type=MyType

Since the default receiver is t and that might cause a lint error if your type has other methods with a different receiver, you can use the -recv argument.

bindec -recv=mt -type=MyType

You can also generate a encoders and decoders for a type from a package that is not your working directory by simply passing the path as an argument after all the other flags.

bindec -recv=somerecv -type=SomeType /path/to/package

If you want to generate encoders and decoders for more than one file and output them in the same file, you can do so passing comma-separated types.

bindec -type=FirstType,SecondType,ThirdType

If you give them receiver names, you must give them in the same order as the types are passed, also comma-separated.

bindec -recv=a,b,c -type=A,B,C
Encode and decode

After generating the code you will have in your package a file yourtype_bindec.go with four methods added to the type: EncodeBinary, WriteBinary, DecodeBinaryFromBytes and DecodeBinary.

// This is our type.
type Person {
    Name string
    Age int
    Gender string
}

// EncodeBinary and DecodeBinary will be on person_bindec.go

// We get some data from somewhere as []byte
data := getSomeDataFromSomewhere()

var p Person
// Then we decode the person from the data.
if err := p.DecodeBinaryFromBytes(data); err != nil {
    // handle err
}

// We can even read it from a reader.
var p2 Person
if err := p.DecodeBinary(reader); err != nil {
    // handle err
}

// And encode it again.
encoded, err := p.EncodeBinary()
if err != nil {
    // handle err
}

// Or write it to a writer.
writer := bytes.NewBuffer(nil)
if err := p.WriteBinary(writer); err != nil {
    // handle err
}
Ignore fields

You may have fields you don't want to encode or decode. You can do so using bindec:"-" struct tag.

type User struct {
    Username string
    Email string
    Password string `bindec:"-"`
}

This way, only Username and Email will be encoded and decoded, but not Password.

Benchmarks

Speed:

goos: darwin
goarch: amd64
pkg: github.com/erizocosmico/bindec/bench
BenchmarkEncode/bindec-4                  500000              2274 ns/op     576 B/op           6 allocs/op
BenchmarkEncode/gob-4                     100000             12464 ns/op    2432 B/op          41 allocs/op
BenchmarkDecode/bindec-4                  500000              2590 ns/op     528 B/op          22 allocs/op
BenchmarkDecode/gob-4                      50000             37126 ns/op    9572 B/op         249 allocs/op
PASS
ok      github.com/erizocosmico/bindec/bench    6.137s

Size:

BINDEC: 112 bytes
GOB: 205 bytes

Benchmarked against encoding/gob on a MacBook Pro (Retina, 13-inch, Early 2015) (2,7 GHz Intel Core i5) on macOS Mojave 10.14.3.

Why not just encoding/gob?

It's slower, takes more space and requires registering every single type that's going to be encoded. bindec offers a fast way to convert a struct into bytes with the smallest possible size. All you need to do is add //go:generate tags to you code and run go generate ./....

In a future version, bindec will support adding validations to the fields during decoding via struct tags, which will allow things like "accept only 100 bytes on this field so an atacker can't send as many bytes as they want" to be performed automatically.

Supported types
  • Integers: byte, int, uint, uint64, ...
  • Floats: float32, float64
  • Strings
  • Maps with keys and values of supported types
  • Pointers
  • Structs (without cyclic references) with fields of supported types
  • Arrays of supported types
  • Slices of supported types
  • Booleans
Limitations
  • Interface, function and channel types are not supported. The reason interfaces are not supported is because they can be anything, potentially even from any package, on runtime and bindec decoders and encoders are generated beforehand.
  • Cyclic structures are not supported.
Specification

For more details about the format used to encode the types, see SPEC.md.

Constraints

TODO.

LICENSE

MIT License, see LICENSE

Documentation

Index

Constants

View Source
const (
	// String type.
	String = types.String
	// Bool type.
	Bool = types.Bool
	// Int type.
	Int = types.Int
	// Int8 type.
	Int8 = types.Int8
	// Int16 type.
	Int16 = types.Int16
	// Int32 type.
	Int32 = types.Int32
	// Int64 type.
	Int64 = types.Int64
	// Uint type.
	Uint = types.Uint
	// Uint8 type.
	Uint8 = types.Uint8
	// Uint16 type.
	Uint16 = types.Uint16
	// Uint32 type.
	Uint32 = types.Uint32
	// Uint64 type.
	Uint64 = types.Uint64
	// Uintptr type.
	Uintptr = types.Uintptr
	// Float32 type.
	Float32 = types.Float32
	// Float64 type.
	Float64 = types.Float64
)

Variables

This section is empty.

Functions

func Generate

func Generate(opts Options) ([]byte, error)

Generate a file of source code containing an encoder and a decoder to encode and decode a given type to and from a binary representation of itself.

Types

type Array

type Array struct {
	Len  int64
	Elem Type
}

Array type of fixed size.

func (Array) Decoder

func (t Array) Decoder(recv string, root bool, constraints ...Constraint) string

Decoder implements the Type interface.

func (Array) Encoder

func (t Array) Encoder(recv string) string

Encoder implements the Type interface.

type Basic

type Basic struct {
	TypeName string
	Kind     BasicKind
}

Basic type.

func (Basic) Decoder

func (t Basic) Decoder(recv string, root bool, constraints ...Constraint) string

Decoder implements the Type interface.

func (Basic) Encoder

func (t Basic) Encoder(recv string) string

Encoder implements the Type interface.

type BasicKind

type BasicKind = types.BasicKind

BasicKind is the kind of basic type.

type Bytes

type Bytes struct {
	TypeName string
}

Bytes is a special type for []byte.

func (Bytes) Decoder

func (t Bytes) Decoder(recv string, root bool, constraints ...Constraint) string

Decoder implements the Type interface.

func (Bytes) Encoder

func (t Bytes) Encoder(recv string) string

Encoder implements the Type interface.

type Constraint

type Constraint interface {
	// BeforeRead returns whether the constraint should be checked before
	// reading the content. This is only applicable to slices and strings.
	BeforeRead() bool
	// Validator generates the code to validate the receiver with the current
	// constraint.
	Validator(recv string) string
}

Constraint to be checked on a struct field.

type Map

type Map struct {
	TypeName, KeyType, ElemType string
	Key                         Type
	Elem                        Type
}

Map type.

func (Map) Decoder

func (t Map) Decoder(recv string, root bool, constraints ...Constraint) string

Decoder implements the Type interface.

func (Map) Encoder

func (t Map) Encoder(recv string) string

Encoder implements the Type interface.

type Maybe

type Maybe struct {
	ElemType string
	Elem     Type
}

Maybe is a type whose value can not be present.

func (Maybe) Decoder

func (t Maybe) Decoder(recv string, root bool, constraints ...Constraint) string

Decoder implements the Type interface.

func (Maybe) Encoder

func (t Maybe) Encoder(recv string) string

Encoder implements the Type interface.

type Options

type Options struct {
	// Path of the package in which the type is located.
	Path string
	// Types to generate encoder and decoder for.
	Types []string
	// Recvs are the receiver names for the generated methods.
	Recvs []string
}

Options to configure generation.

type Slice

type Slice struct {
	TypeName string
	Elem     Type
}

Slice type.

func (Slice) Decoder

func (t Slice) Decoder(recv string, root bool, constraints ...Constraint) string

Decoder implements the Type interface.

func (Slice) Encoder

func (t Slice) Encoder(recv string) string

Encoder implements the Type interface.

type Struct

type Struct struct {
	Fields []StructField
}

Struct type.

func (Struct) Decoder

func (t Struct) Decoder(recv string, root bool, constraints ...Constraint) string

Decoder implements the Type interface.

func (Struct) Encoder

func (t Struct) Encoder(recv string) string

Encoder implements the Type interface.

type StructField

type StructField struct {
	Name        string
	Type        Type
	Constraints []Constraint
}

StructField is a field in a struct.

type Type

type Type interface {
	// Decoder generates a decoder for the type. recv is the variable or
	// struct field the data will be decoded into.
	// If root is true, it means the decoder is being generated for a recv
	// itself.
	Decoder(recv string, root bool, constraints ...Constraint) string
	// Encoder generates an encoder for the type. recv is the variable or
	// struct field that will be encoded.
	Encoder(recv string) string
}

Type can generate decoders and encoders for a given type.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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