bundle

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2020 License: MIT Imports: 5 Imported by: 2

README

CI GitHub release

Hits-of-Code Lines of code

Simple binary encoding and decoding tool, a type-safe wrapper for encoding/binary package.

Implements BinaryMarshaler and BinaryUnmarshaler from encoding, supports different encoding.BiteOrders. Errors accumulator to avoid each line error checks. It could be useful to implement custom encoding binary protocols.

The problem

Go has a package encoding/binary for binary serialization, it provides good and low-level API for encoding. The problem is that it's not really handy and requires a lot of boilerplate code to read and write data to stream, such as: lack of type safety (accepts interface{} params) error-checks for each line, custom array/slice encoding/decoding protocols, custom nested encoding/decoding.

This library aims to solve these issues by providing type-safe and extended wrapper over encoding/binary package which reduce the amount of bolierplate codes and ensures type-safety.

Since it uses encoding/binary under the hood, keep in mind that:

This package favors simplicity over efficiency. Clients that require high-performance serialization, especially for large data structures, should look at more advanced solutions such as the encoding/gob package or protocol buffers.

Install

Add to imports: "github.com/g4s8/go-bundle"

Usage

The bundle package provides two main types: Out and Inp. Out (output) is used to put data into bundle and produce byte array from it, Inp (input) is used to read data from bytes array.

Output

Create new bundle output

There are different factory functions to create bundle outputs:

out := NewOut(order) // creates bundle and specify byte order
outBE := NewBEOut() // creates bundle with big-endian byte order
outLE := NewLEOut() // creates bundle with little-endian byte order
Put data into bundle

Each out bundle method has type-name suffix and accepts only fixed-length and strongly typed parameters:

out := NewBEOut()
out.PutInt32(int32(42))
out.PutUIint64(uint64(1111111111111))
out.PutFloat32(float32(1.4))
out.PutBytes([]byte{0x00, 0x01, 0x02})
out.PutString("hello bundle!")

Also, output accepts encoding.BinaryMarshaler types to put: out.PutBinary(binary).

Nested bundles

Bundle can contain nested bundles, to put one bundle into another use PutBundle method:

parent := NewLEOut()
nested := NewLEOut()
parent.PutBundle(nested)
Errors

Output Put* methods doesn't return errors, but in case of error it will be accumulated. It can be checked with out.Error() method. If error happens, put method won't try to put next values to internal bytes buffer.

Marshaling

Output implements encoding.BinaryMarshaler protocol. It can be used to get byte array of the bundle:

out := NewBEOut()
out.PutInt32(int32(42))
bytes, err := out.MarshalBinary()

It returns buffer bytes or first error.

Flip

Flip methods creates input from output: func (o *Out) Flip() *Inp. It can be useful for testing.

Input

Creating new input

These factory functions can be used to wrap byte array with bundle input type:


i1 := NewInput(order) // creates input with specified order
i1 := NewBEInput() // creates big-endian input
i3 := NewLEInput() // creates little-endian input
i4 := InpWrapBytes(order, bts) // creates input from bytes with order
Filling input with data

Bundle input implements encoding.BinaryUnmarshaler protocol, it means it can be read from byte array:

inp := NewInput(binary.BigEndian)
err := inp.UnmarshalBinary(data)

Alternatively, it can be constructed directly from bytes using wrap factory method:

inp := InpWrapBytes(order, bytes)

Input can't be read twise, the call to UnmarshalBinary returns an error if input was already read.

Reading data from input

Input bundle methods has type suffixes and accepts output reference parameters to read the data:

// Reads int32
var i32 int32
inp.ReadInt32(&i32)

// Reads byte-array
var bts []byte
inp.ReadBytes(&bts)

// Read binary unmarshaler
// subInput - implements `encoding.BinaryUnmarshaler`
inp.ReadBinary(subInput)
Reading nested bundles

Inp can contain nested bundles, to read it create new empty Inp with new(Inp) and read it from parent bundle:

// var parent Inp
nested := new(Inp)
parent.GetBundle(nested)
Errors

Errors are accumulated and can be accessed with Error() method. In case of error, next read methods won't be performed.

Example

Assuming you need to implement encoding.BinaryMarshaler and encoding.BinaryUnmarshaler for some struct. You can use bundle to do that:

import (
  "encoding/binary"
  "github.com/g4s8/go-bundle"
  ma "github.com/multiformats/go-multiaddr"
)

type Foo struct {
  ID int32
  Description string
  internal []byte
  Addr ma.Multiaddr
}

var byteOrder = binary.BigEndian

func (f *Foo) MarshalBinary() ([]byte, error) {
  out := bundle.NewOut(byteOrder)
  out.PutInt32(f.ID)
  out.PutString(f.Description)
  out.PutBytes(f.internal)
  out.PutBinary(f.Addr)
  return out.MarshalBinary()
}

func (f *Foo) UnmarshalBinary(data []byte) error {
  inp := bundle.NewInput(byteOrder)
  if err := inp.UnmarshalBinary(data); err != nil {
         return err
  }
  inp.GetInt32(&f.ID)
  inp.GetString(&f.Description)
  inp.GetBytes(&f.internal)
  var rawAddr []byte
  inp.GetBytes(&rawAddr)
  addr, err := ma.NewMultiaddrBytes(rawAddr)
  if err != nil {
    return err
  }
  f.Addr = addr
  return nil
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Inp

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

Inp is bundle input type, it wraps source byte array and read data with specified bytes order

func InpWrapBytes added in v0.1.1

func InpWrapBytes(bts []byte, order binary.ByteOrder) *Inp

InpWrapBytes creates new input from bytes source with specified byte order.

func NewBEInput

func NewBEInput() *Inp

NewBEInput creates new empty input with big-endian byte order, the data could be added with `UnmarshalBinary` method.

func NewInput

func NewInput(order binary.ByteOrder) *Inp

NewInput creates new empty input with specified byte order, the data could be added with `UnmarshalBinary` method.

func NewLEInput

func NewLEInput() *Inp

NewBEInput creates new empty input with little-endian byte order, the data could be added with `UnmarshalBinary` method.

func (*Inp) Error

func (i *Inp) Error() error

func (*Inp) GetBinary

func (i *Inp) GetBinary(bin encoding.BinaryUnmarshaler)

GetBinary reads marshaled type to binary unmarshaler

func (*Inp) GetBool added in v0.1.1

func (i *Inp) GetBool(out *bool)

GetBool reads bool type to `out` param

func (*Inp) GetBundle added in v0.1.1

func (i *Inp) GetBundle(b *Inp)

func (*Inp) GetBytes

func (i *Inp) GetBytes(out *[]byte)

GetBytes reads byte array to `out` param

func (*Inp) GetFloat32 added in v0.1.1

func (i *Inp) GetFloat32(out *float32)

GetFloat32 reads float32 to `out` param

func (*Inp) GetFloat64 added in v0.1.1

func (i *Inp) GetFloat64(out *float64)

GetFloat64 reads float64 to `out` param

func (*Inp) GetInt16 added in v0.1.1

func (i *Inp) GetInt16(out *int16)

GetInt16 reads int16 type to `out` param

func (*Inp) GetInt32

func (i *Inp) GetInt32(out *int32)

GetInt32 reads int32 type to `out` param

func (*Inp) GetInt64

func (i *Inp) GetInt64(out *int64)

GetInt64 reads int64 type to `out` param

func (*Inp) GetInt8 added in v0.1.1

func (i *Inp) GetInt8(out *int8)

GetInt8 reads int8 type to `out` param

func (*Inp) GetRune added in v0.1.1

func (i *Inp) GetRune(out *rune)

GetRune reads rune type to `out` param

func (*Inp) GetString added in v0.1.1

func (i *Inp) GetString(out *string)

GetString reads strig from bundle

func (*Inp) GetUInt16 added in v0.1.1

func (i *Inp) GetUInt16(out *uint16)

GetUInt16 reads uint16 type to `out` param

func (*Inp) GetUInt32

func (i *Inp) GetUInt32(out *uint32)

GetUInt32 reads uint32 type to `out` param

func (*Inp) GetUInt64

func (i *Inp) GetUInt64(out *uint64)

GetUInt64 reads uint64 type to `out` param

func (*Inp) GetUInt8 added in v0.1.1

func (i *Inp) GetUInt8(out *uint8)

GetUInt8 reads int8 type to `out` param

func (*Inp) GetUInts8

func (i *Inp) GetUInts8(out *[]uint8)

GetUInts8 reads unit8 array to `out` param

func (*Inp) GoString added in v0.1.1

func (i *Inp) GoString() string

func (*Inp) String added in v0.1.1

func (i *Inp) String() string

func (*Inp) UnmarshalBinary

func (i *Inp) UnmarshalBinary(data []byte) error

type Out

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

Out bundle of binary data to write

func NewBEOut

func NewBEOut() *Out

NewBEOut creates new output with big-endian byte order

func NewLEOut

func NewLEOut() *Out

NewLEOut creates new output with little-endian byte order

func NewOut

func NewOut(order binary.ByteOrder) *Out

NewOut creates empty output to write data

func (*Out) Error

func (o *Out) Error() error

func (*Out) Flip added in v0.1.1

func (o *Out) Flip() *Inp

Flip bundle onput to input

func (*Out) MarshalBinary

func (o *Out) MarshalBinary() ([]byte, error)

func (*Out) PutBinary

func (o *Out) PutBinary(bin encoding.BinaryMarshaler)

PutBinary puts binary marshaler to bundle

func (*Out) PutBool added in v0.1.1

func (o *Out) PutBool(x bool)

PutBool buts a bool to bundle

func (*Out) PutBundle added in v0.1.1

func (o *Out) PutBundle(b *Out)

PutBundle puts nested bundle

func (*Out) PutByte

func (o *Out) PutByte(x byte)

PutByte puts a byte to bundle

func (*Out) PutBytes

func (o *Out) PutBytes(x []byte)

PutBytes puts byte array to bundle

func (*Out) PutFloat32

func (o *Out) PutFloat32(x float32)

PutFloat32 puts float32 to bundle

func (*Out) PutFloat64

func (o *Out) PutFloat64(x float64)

PutFloat64 puts float64 to bundle

func (*Out) PutInt16

func (o *Out) PutInt16(x int16)

PutInt16 puts int16 to bundle

func (*Out) PutInt32

func (o *Out) PutInt32(x int32)

PutInt32 puts int32 to bundle

func (*Out) PutInt64

func (o *Out) PutInt64(x int64)

PutInt64 puts int64 to bundle

func (*Out) PutInt8

func (o *Out) PutInt8(x int8)

PutInt8 puts int8 to bundle

func (*Out) PutRune added in v0.1.1

func (o *Out) PutRune(x rune)

PutRune puts rune to bundle

func (*Out) PutString added in v0.1.1

func (o *Out) PutString(s string)

PutString puts string to bundle

func (*Out) PutUInt16

func (o *Out) PutUInt16(x uint16)

PutUInt16 puts uint16 to bundle

func (*Out) PutUInt32

func (o *Out) PutUInt32(x uint32)

PutUInt32 puts uint32 to bundle

func (*Out) PutUInt64

func (o *Out) PutUInt64(x uint64)

PutUInt64 puts uint64 to bundle

func (*Out) PutUInt8

func (o *Out) PutUInt8(x uint8)

PutUInt8 puts uint8 to bundle

func (*Out) PutUInts8 added in v0.1.1

func (o *Out) PutUInts8(x []uint8)

PutUInts8 puts uint8 array to bundle

Jump to

Keyboard shortcuts

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