wire

package
v0.0.0-...-c187892 Latest Latest
Warning

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

Go to latest
Published: Mar 11, 2016 License: GPL-2.0, GPL-3.0, GPL-3.0 Imports: 15 Imported by: 0

README

NOTICE

This documentation is out of date.

  • 0x00 is reserved as a nil byte for RegisterInterface
  • moved TypeByte() into RegisterInterface/ConcreteType
  • Pointers that don't have a declared TypeByte() are encoded with a leading 0x00 (nil) or 0x01.

tendermint/wire

The binary submodule encodes primary types and structs into bytes.

Primary types

uint*, int*, string, time, byteslice and byteslice-slice types can be encoded and decoded with the following methods:

The following writes o uint64 to w io.Writer, and increments n and/or sets err

WriteUint64(o uint64, w io.Writer, n *int64, err *error)

// Typical usage:
buf, n, err := new(bytes.Buffer), new(int64), new(error)
WriteUint64(uint64(x), buf, n, err)
if *err != nil {
    panic(err)
}

The following reads a uint64 from r io.Reader, and increments n and/or sets err

var o = ReadUint64(r io.Reader, n *int64, err *error)

Similar methods for uint32, uint16, uint8, int64, int32, int16, int8 exist. Protobuf variable length encoding is done with uint and int types:

WriteUvarint(o uint, w io.Writer, n *int64, err *error)
var o = ReadUvarint(r io.Reader, n *int64, err *error)

Byteslices can be written with:

WriteByteSlice(bz []byte, w io.Writer, n *int64, err *error)

Byteslices (and all slices such as byteslice-slices) are prepended with uvarint encoded length, so ReadByteSlice() knows how many bytes to read.

Note that there is no type information encoded -- the caller is assumed to know what types to decode.

Struct Types

Struct types can be automatically encoded with reflection. Unlike json-encoding, no field name or type information is encoded. Field values are simply encoded in order.

type Foo struct {
    MyString        string
    MyUint32        uint32
    myPrivateBytes  []byte
}

foo := Foo{"my string", math.MaxUint32, []byte("my private bytes")}

buf, n, err := new(bytes.Buffer), new(int64), new(error)
WriteBinary(foo, buf, n, err)

// fmt.Printf("%X", buf.Bytes()) gives:
// 096D7920737472696E67FFFFFFFF
// 09:                           uvarint encoded length of string "my string"
//   6D7920737472696E67:         bytes of string "my string"
//                     FFFFFFFF: bytes for MaxUint32 
// Note that the unexported "myPrivateBytes" isn't encoded.

foo2 := ReadBinary(Foo{}, buf, n, err).(Foo)

// Or, to decode onto a pointer:
foo2 := ReadBinaryPtr(&Foo{}, buf, n, err).(*Foo)

WriteBinary and ReadBinary can encode/decode structs recursively. However, interface field values are a bit more complicated.

type Greeter interface {
	Greet() string
}

type Dog struct{}
func (d Dog) Greet() string { return "Woof!" }

type Cat struct{}
func (c Cat) Greet() string { return "Meow!" }

type Foo struct {
	Greeter
}

foo := Foo{Dog{}}

buf, n, err := new(bytes.Buffer), new(int64), new(error)
WriteBinary(foo, buf, n, err)

// This errors because we don't know whether to read a Dog or Cat.
foo2 := ReadBinary(Foo{}, buf, n, err)

In the above example, ReadBinary() fails because the Greeter field for Foo{} is ambiguous -- it could be either a Dog{} or a Cat{}, like a union structure. The solution is to declare the concrete implementation types for interfaces:

type Dog struct{}
func (d Dog) TypeByte() byte { return GreeterTypeDog }
func (d Dog) Greet() string { return "Woof!" }

type Cat struct{}
func (c Cat) TypeByte() byte { return GreeterTypeCat }
func (c Cat) Greet() string { return "Meow!" }

var _ = RegisterInterface(
	struct{Greeter}{},
	ConcreteType{Dog{}},
	ConcreteType{Cat{}},
})

NOTE: The TypeByte() is written and expected to be read even when the struct is encoded or decoded directly:

WriteBinary(Dog{}, buf, n, err)        // Writes GreeterTypeDog byte
dog_ := ReadBinary(Dog{}, buf, n, err) // Expects to read GreeterTypeDog byte
dog := dog_.(Dog)                      // ok if *err != nil, otherwise dog_ == nil.

Documentation

Index

Constants

View Source
const MaxBinaryReadSize = 21 * 1024 * 1024

TODO document and maybe make it configurable.

View Source
const (
	ReflectSliceChunk = 1024
)
View Source
const Version = "0.5.0"

Variables

View Source
var BasicCodec = Codec{
	Encode:  BasicCodecEncoder,
	Decode:  BasicCodecDecoder,
	Compare: BasicCodecComparator,
}
View Source
var ErrBinaryReadSizeOverflow = errors.New("Error: binary read size overflow")
View Source
var ErrBinaryReadSizeUnderflow = errors.New("Error: binary read size underflow")

Functions

func BasicCodecComparator

func BasicCodecComparator(o1 interface{}, o2 interface{}) int

Contract: Caller must ensure that types match.

func BasicCodecDecoder

func BasicCodecDecoder(r io.Reader, n *int64, err *error) (o interface{})

func BasicCodecEncoder

func BasicCodecEncoder(o interface{}, w io.Writer, n *int64, err *error)

func BinaryBytes

func BinaryBytes(o interface{}) []byte

func BinaryCompare

func BinaryCompare(a, b interface{}) int

NOTE: does not care about the type, only the binary representation.

func BinaryEqual

func BinaryEqual(a, b interface{}) bool

NOTE: does not care about the type, only the binary representation.

func BinaryRipemd160

func BinaryRipemd160(o interface{}) []byte

NOTE: The default hash function is Ripemd160.

func BinarySha256

func BinarySha256(o interface{}) []byte

NOTE: only use this if you need 32 bytes.

func GetTypeFromStructDeclaration

func GetTypeFromStructDeclaration(o interface{}) reflect.Type

e.g. If o is struct{Foo}{}, return is the Foo reflection type.

func JSONBytes

func JSONBytes(o interface{}) []byte

func ReadBinary

func ReadBinary(o interface{}, r io.Reader, n *int64, err *error) interface{}

func ReadBinaryPtr

func ReadBinaryPtr(o interface{}, r io.Reader, n *int64, err *error) interface{}

func ReadByte

func ReadByte(r io.Reader, n *int64, err *error) byte

func ReadByteSlice

func ReadByteSlice(r io.Reader, n *int64, err *error) []byte

func ReadByteSlices

func ReadByteSlices(r io.Reader, n *int64, err *error) [][]byte

func ReadFull

func ReadFull(buf []byte, r io.Reader, n *int64, err *error)

Read len(buf) from r Increment n and set err accordingly.

func ReadInt16

func ReadInt16(r io.Reader, n *int64, err *error) int16

func ReadInt32

func ReadInt32(r io.Reader, n *int64, err *error) int32

func ReadInt64

func ReadInt64(r io.Reader, n *int64, err *error) int64

func ReadInt8

func ReadInt8(r io.Reader, n *int64, err *error) int8

func ReadJSON

func ReadJSON(o interface{}, bytes []byte, err *error) interface{}

func ReadJSONObject

func ReadJSONObject(o interface{}, object interface{}, err *error) interface{}

o is the ultimate destination, object is the result of json unmarshal

func ReadJSONObjectPtr

func ReadJSONObjectPtr(o interface{}, object interface{}, err *error) interface{}

func ReadJSONPtr

func ReadJSONPtr(o interface{}, bytes []byte, err *error) interface{}

func ReadString

func ReadString(r io.Reader, n *int64, err *error) string

func ReadTime

func ReadTime(r io.Reader, n *int64, err *error) time.Time

func ReadUint16

func ReadUint16(r io.Reader, n *int64, err *error) uint16

func ReadUint16s

func ReadUint16s(r io.Reader, n *int64, err *error) []uint16

func ReadUint32

func ReadUint32(r io.Reader, n *int64, err *error) uint32

func ReadUint64

func ReadUint64(r io.Reader, n *int64, err *error) uint64

func ReadUint8

func ReadUint8(r io.Reader, n *int64, err *error) uint8

func ReadUvarint

func ReadUvarint(r io.Reader, n *int64, err *error) uint

func ReadVarint

func ReadVarint(r io.Reader, n *int64, err *error) int

func SetByteForType

func SetByteForType(typeByte byte, rt reflect.Type)

func WriteBinary

func WriteBinary(o interface{}, w io.Writer, n *int64, err *error)

func WriteByte

func WriteByte(b byte, w io.Writer, n *int64, err *error)

func WriteByteSlice

func WriteByteSlice(bz []byte, w io.Writer, n *int64, err *error)

func WriteByteSlices

func WriteByteSlices(bzz [][]byte, w io.Writer, n *int64, err *error)

func WriteInt16

func WriteInt16(i int16, w io.Writer, n *int64, err *error)

func WriteInt32

func WriteInt32(i int32, w io.Writer, n *int64, err *error)

func WriteInt64

func WriteInt64(i int64, w io.Writer, n *int64, err *error)

func WriteInt8

func WriteInt8(i int8, w io.Writer, n *int64, err *error)

func WriteJSON

func WriteJSON(o interface{}, w io.Writer, n *int64, err *error)

func WriteString

func WriteString(s string, w io.Writer, n *int64, err *error)

func WriteTime

func WriteTime(t time.Time, w io.Writer, n *int64, err *error)

func WriteTo

func WriteTo(bz []byte, w io.Writer, n *int64, err *error)

Write all of bz to w Increment n and set err accordingly.

func WriteUint16

func WriteUint16(i uint16, w io.Writer, n *int64, err *error)

func WriteUint16s

func WriteUint16s(iz []uint16, w io.Writer, n *int64, err *error)

func WriteUint32

func WriteUint32(i uint32, w io.Writer, n *int64, err *error)

func WriteUint64

func WriteUint64(i uint64, w io.Writer, n *int64, err *error)

func WriteUint8

func WriteUint8(i uint8, w io.Writer, n *int64, err *error)

func WriteUvarint

func WriteUvarint(i uint, w io.Writer, n *int64, err *error)

func WriteVarint

func WriteVarint(i int, w io.Writer, n *int64, err *error)

Types

type Codec

type Codec struct {
	Encode  Encoder
	Decode  Decoder
	Compare Comparator
}

type Comparator

type Comparator func(o1 interface{}, o2 interface{}) int

type ConcreteType

type ConcreteType struct {
	O    interface{}
	Byte byte
}

For use with the RegisterInterface declaration

type Decoder

type Decoder func(r io.Reader, n *int64, err *error) interface{}

type Encoder

type Encoder func(o interface{}, w io.Writer, n *int64, err *error)

type Options

type Options struct {
	JSONName string // (JSON) Corresponding JSON field name. (override with `json=""`)
	Varint   bool   // (Binary) Use length-prefixed encoding for (u)int*
}

type StructFieldInfo

type StructFieldInfo struct {
	Index   int          // Struct field index
	Type    reflect.Type // Struct field type
	Options              // Encoding options
}

type TypeInfo

type TypeInfo struct {
	Type reflect.Type // The type

	// If Type is kind reflect.Interface, is registered
	IsRegisteredInterface bool
	ByteToType            map[byte]reflect.Type
	TypeToByte            map[reflect.Type]byte

	// If Type is concrete
	Byte byte

	// If Type is kind reflect.Struct
	Fields []StructFieldInfo
}

func GetTypeInfo

func GetTypeInfo(rt reflect.Type) *TypeInfo

func MakeTypeInfo

func MakeTypeInfo(rt reflect.Type) *TypeInfo

func RegisterInterface

func RegisterInterface(o interface{}, ctypes ...ConcreteType) *TypeInfo

Must use this to register an interface to properly decode the underlying concrete type.

Jump to

Keyboard shortcuts

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