msgpack

package module
Version: v2.9.2 Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2021 License: BSD-3-Clause Imports: 13 Imported by: 265

README

MessagePack encoding for Golang

Build Status GoDoc

Supports:

  • Primitives, arrays, maps, structs, time.Time and interface{}.
  • Appengine *datastore.Key and datastore.Cursor.
  • CustomEncoder/CustomDecoder interfaces for custom encoding.
  • Extensions to encode type information.
  • Renaming fields via msgpack:"my_field_name".
  • Inlining struct fields via msgpack:",inline".
  • Omitting empty fields via msgpack:",omitempty".
  • Map keys sorting.
  • Encoding/decoding all structs as arrays or individual structs.
  • Simple but very fast and efficient queries.

API docs: https://godoc.org/gopkg.in/vmihailenco/msgpack.v2. Examples: https://godoc.org/gopkg.in/vmihailenco/msgpack.v2#pkg-examples.

Installation

Install:

go get gopkg.in/vmihailenco/msgpack.v2

Quickstart

func ExampleMarshal() {
	type Item struct {
		Foo string
	}

	b, err := msgpack.Marshal(&Item{Foo: "bar"})
	if err != nil {
		panic(err)
	}

	var item Item
	err = msgpack.Unmarshal(b, &item)
	if err != nil {
		panic(err)
	}
	fmt.Println(item.Foo)
	// Output: bar
}

Benchmark

BenchmarkStructVmihailencoMsgpack-4   	  200000	     12814 ns/op	    2128 B/op	      26 allocs/op
BenchmarkStructUgorjiGoMsgpack-4      	  100000	     17678 ns/op	    3616 B/op	      70 allocs/op
BenchmarkStructUgorjiGoCodec-4        	  100000	     19053 ns/op	    7346 B/op	      23 allocs/op
BenchmarkStructJSON-4                 	   20000	     69438 ns/op	    7864 B/op	      26 allocs/op
BenchmarkStructGOB-4                  	   10000	    104331 ns/op	   14664 B/op	     278 allocs/op

Howto

Please go through examples to get an idea how to use this package.

See also

Documentation

Overview

Example (DecodeMapStringString)
decodedMap := make(map[string]string)
buf := &bytes.Buffer{}

m := map[string]string{"foo1": "bar1", "foo2": "bar2", "foo3": "bar3"}
keys := []string{"foo1", "foo3", "foo2"}

encodedMap, err := encodeMap(m, keys...)
if err != nil {
	panic(err)
}

_, err = buf.Write(encodedMap)
if err != nil {
	panic(err)
}

decoder := msgpack.NewDecoder(buf)

n, err := decoder.DecodeMapLen()
if err != nil {
	panic(err)
}

for i := 0; i < n; i++ {
	key, err := decoder.DecodeString()
	if err != nil {
		panic(err)
	}
	value, err := decoder.DecodeString()
	if err != nil {
		panic(err)
	}
	decodedMap[key] = value
}

for _, key := range keys {
	fmt.Printf("%#v: %#v, ", key, decodedMap[key])
}
Output:

"foo1": "bar1", "foo3": "bar3", "foo2": "bar2",
Example (EncodeMapStringString)
buf := &bytes.Buffer{}

m := map[string]string{"foo1": "bar1", "foo2": "bar2", "foo3": "bar3"}
keys := []string{"foo1", "foo3"}

encodedMap, err := encodeMap(m, keys...)
if err != nil {
	panic(err)
}

_, err = buf.Write(encodedMap)
if err != nil {
	panic(err)
}

decoder := msgpack.NewDecoder(buf)
value, err := decoder.DecodeMap()
if err != nil {
	panic(err)
}

decodedMapValue := value.(map[interface{}]interface{})

for _, key := range keys {
	fmt.Printf("%#v: %#v, ", key, decodedMapValue[key])
}
Output:

"foo1": "bar1", "foo3": "bar3",

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal

func Marshal(v ...interface{}) ([]byte, error)

Marshal returns the MessagePack encoding of v.

Example
type Item struct {
	Foo string
}

b, err := msgpack.Marshal(&Item{Foo: "bar"})
if err != nil {
	panic(err)
}

var item Item
err = msgpack.Unmarshal(b, &item)
if err != nil {
	panic(err)
}
fmt.Println(item.Foo)
Output:

bar
Example (AsArray)
type Item struct {
	_msgpack struct{} `msgpack:",asArray"`
	Foo      string
	Bar      string
}

var buf bytes.Buffer
enc := msgpack.NewEncoder(&buf)
err := enc.Encode(&Item{Foo: "foo", Bar: "bar"})
if err != nil {
	panic(err)
}

dec := msgpack.NewDecoder(&buf)
v, err := dec.DecodeInterface()
if err != nil {
	panic(err)
}
fmt.Println(v)
Output:

[foo bar]
Example (MapStringInterface)
in := map[string]interface{}{"foo": 1, "hello": "world"}
b, err := msgpack.Marshal(in)
if err != nil {
	panic(err)
}

var out map[string]interface{}
err = msgpack.Unmarshal(b, &out)
if err != nil {
	panic(err)
}

fmt.Println("foo =", out["foo"])
fmt.Println("hello =", out["hello"])
Output:

foo = 1
hello = world
Example (RecursiveMapStringInterface)
buf := new(bytes.Buffer)

enc := msgpack.NewEncoder(buf)
in := map[string]interface{}{"foo": map[string]interface{}{"hello": "world"}}
_ = enc.Encode(in)

dec := msgpack.NewDecoder(buf)
dec.DecodeMapFunc = func(d *msgpack.Decoder) (interface{}, error) {
	n, err := d.DecodeMapLen()
	if err != nil {
		return nil, err
	}

	m := make(map[string]interface{}, n)
	for i := 0; i < n; i++ {
		mk, err := d.DecodeString()
		if err != nil {
			return nil, err
		}

		mv, err := d.DecodeInterface()
		if err != nil {
			return nil, err
		}

		m[mk] = mv
	}
	return m, nil
}

out, err := dec.DecodeInterface()
if err != nil {
	panic(err)
}
fmt.Println(out)
Output:

map[foo:map[hello:world]]

func Register

func Register(typ reflect.Type, enc encoderFunc, dec decoderFunc)

Register registers encoder and decoder functions for a type. In most cases you should prefer implementing CustomEncoder and CustomDecoder interfaces.

func RegisterExt added in v2.4.1

func RegisterExt(id int8, value interface{})

RegisterExt records a type, identified by a value for that type, under the provided id. That id will identify the concrete type of a value sent or received as an interface variable. Only types that will be transferred as implementations of interface values need to be registered. Expecting to be used only during initialization, it panics if the mapping between types and ids is not a bijection.

Example
package main

import (
	"encoding/binary"
	"fmt"
	"time"

	"gopkg.in/vmihailenco/msgpack.v2"
)

func init() {
	msgpack.RegisterExt(0, &EventTime{})
}

// https://github.com/fluent/fluentd/wiki/Forward-Protocol-Specification-v1#eventtime-ext-format
type EventTime struct {
	time.Time
}

var _ msgpack.Marshaler = (*EventTime)(nil)
var _ msgpack.Unmarshaler = (*EventTime)(nil)

func (tm *EventTime) MarshalMsgpack() ([]byte, error) {
	b := make([]byte, 8)
	binary.BigEndian.PutUint32(b, uint32(tm.Unix()))
	binary.BigEndian.PutUint32(b[4:], uint32(tm.Nanosecond()))
	return b, nil
}

func (tm *EventTime) UnmarshalMsgpack(b []byte) error {
	if len(b) != 8 {
		return fmt.Errorf("invalid data length: got %d, wanted 8", len(b))
	}
	sec := binary.BigEndian.Uint32(b)
	usec := binary.BigEndian.Uint32(b[4:])
	tm.Time = time.Unix(int64(sec), int64(usec))
	return nil
}

func main() {
	b, err := msgpack.Marshal(&EventTime{time.Unix(123456789, 123)})
	if err != nil {
		panic(err)
	}

	var v interface{}
	err = msgpack.Unmarshal(b, &v)
	if err != nil {
		panic(err)
	}
	fmt.Println(v.(EventTime).UTC())

	var tm EventTime
	err = msgpack.Unmarshal(b, &tm)
	if err != nil {
		panic(err)
	}
	fmt.Println(tm.UTC())

}
Output:

1973-11-29 21:33:09.000000123 +0000 UTC
1973-11-29 21:33:09.000000123 +0000 UTC

func Unmarshal

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

Unmarshal decodes the MessagePack-encoded data and stores the result in the value pointed to by v.

Types

type CustomDecoder added in v2.2.1

type CustomDecoder interface {
	DecodeMsgpack(*Decoder) error
}

type CustomEncoder added in v2.2.1

type CustomEncoder interface {
	EncodeMsgpack(*Encoder) error
}
Example
package main

import (
	"fmt"

	"gopkg.in/vmihailenco/msgpack.v2"
)

type customStruct struct {
	S string
	N int
}

var _ msgpack.CustomEncoder = (*customStruct)(nil)
var _ msgpack.CustomDecoder = (*customStruct)(nil)

func (s *customStruct) EncodeMsgpack(enc *msgpack.Encoder) error {
	return enc.Encode(s.S, s.N)
}

func (s *customStruct) DecodeMsgpack(dec *msgpack.Decoder) error {
	return dec.Decode(&s.S, &s.N)
}

func main() {
	b, err := msgpack.Marshal(&customStruct{S: "hello", N: 42})
	if err != nil {
		panic(err)
	}

	var v customStruct
	err = msgpack.Unmarshal(b, &v)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v", v)
}
Output:

msgpack_test.customStruct{S:"hello", N:42}

type Decoder

type Decoder struct {
	DecodeMapFunc func(*Decoder) (interface{}, error)
	// contains filtered or unexported fields
}

func NewDecoder

func NewDecoder(r io.Reader) *Decoder

func (*Decoder) Buffered added in v2.9.2

func (d *Decoder) Buffered() io.Reader

Buffered returns a reader of the data remaining in the Decoder's buffer. The reader is valid until the next call to Decode.

func (*Decoder) Decode

func (d *Decoder) Decode(v ...interface{}) error

func (*Decoder) DecodeArrayLen added in v2.6.1

func (d *Decoder) DecodeArrayLen() (int, error)

func (*Decoder) DecodeBool

func (d *Decoder) DecodeBool() (bool, error)

func (*Decoder) DecodeBytes

func (d *Decoder) DecodeBytes() ([]byte, error)

func (*Decoder) DecodeBytesLen

func (d *Decoder) DecodeBytesLen() (int, error)

func (*Decoder) DecodeFloat32

func (d *Decoder) DecodeFloat32() (float32, error)

func (*Decoder) DecodeFloat64

func (d *Decoder) DecodeFloat64() (float64, error)

func (*Decoder) DecodeInt

func (d *Decoder) DecodeInt() (int, error)

func (*Decoder) DecodeInt16

func (d *Decoder) DecodeInt16() (int16, error)

func (*Decoder) DecodeInt32

func (d *Decoder) DecodeInt32() (int32, error)

func (*Decoder) DecodeInt64

func (d *Decoder) DecodeInt64() (int64, error)

func (*Decoder) DecodeInt8

func (d *Decoder) DecodeInt8() (int8, error)

func (*Decoder) DecodeInterface

func (d *Decoder) DecodeInterface() (interface{}, error)

DecodeInterface decodes value into interface. Possible value types are:

- nil,
- bool,
- int64 for negative numbers,
- uint64 for positive numbers,
- float32 and float64,
- string,
- slices of any of the above,
- maps of any of the above.

func (*Decoder) DecodeMap

func (d *Decoder) DecodeMap() (interface{}, error)

func (*Decoder) DecodeMapLen

func (d *Decoder) DecodeMapLen() (int, error)

func (*Decoder) DecodeNil added in v2.2.1

func (d *Decoder) DecodeNil() error

func (*Decoder) DecodeSlice

func (d *Decoder) DecodeSlice() ([]interface{}, error)

func (*Decoder) DecodeSliceLen

func (d *Decoder) DecodeSliceLen() (int, error)

Deprecated. Use DecodeArrayLen instead.

func (*Decoder) DecodeString

func (d *Decoder) DecodeString() (string, error)

func (*Decoder) DecodeTime

func (d *Decoder) DecodeTime() (time.Time, error)

func (*Decoder) DecodeUint

func (d *Decoder) DecodeUint() (uint, error)

func (*Decoder) DecodeUint16

func (d *Decoder) DecodeUint16() (uint16, error)

func (*Decoder) DecodeUint32

func (d *Decoder) DecodeUint32() (uint32, error)

func (*Decoder) DecodeUint64

func (d *Decoder) DecodeUint64() (uint64, error)

func (*Decoder) DecodeUint8

func (d *Decoder) DecodeUint8() (uint8, error)

func (*Decoder) DecodeValue

func (d *Decoder) DecodeValue(v reflect.Value) error

func (*Decoder) PeekCode added in v2.5.1

func (d *Decoder) PeekCode() (code byte, err error)

peekCode returns next MessagePack code. See https://github.com/msgpack/msgpack/blob/master/spec.md#formats for details.

func (*Decoder) Query added in v2.6.0

func (d *Decoder) Query(query string) ([]interface{}, error)

Query extracts data specified by the query from the msgpack stream skipping any other data. Query consists of map keys and array indexes separated with dot, e.g. key1.0.key2.

Example
b, err := msgpack.Marshal([]map[string]interface{}{
	{"id": 1, "attrs": map[string]interface{}{"phone": 12345}},
	{"id": 2, "attrs": map[string]interface{}{"phone": 54321}},
})
if err != nil {
	panic(err)
}

dec := msgpack.NewDecoder(bytes.NewBuffer(b))
values, err := dec.Query("*.attrs.phone")
if err != nil {
	panic(err)
}
fmt.Println("phones are", values)

dec.Reset(bytes.NewBuffer(b))
values, err = dec.Query("1.attrs.phone")
if err != nil {
	panic(err)
}
fmt.Println("2nd phone is", values[0])
Output:

phones are [12345 54321]
2nd phone is 54321

func (*Decoder) Reset added in v2.6.0

func (d *Decoder) Reset(r io.Reader) error

func (*Decoder) Skip added in v2.4.5

func (d *Decoder) Skip() error

Skip skips next value.

type Encoder

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

func NewEncoder

func NewEncoder(w io.Writer) *Encoder

func (*Encoder) Encode

func (e *Encoder) Encode(v ...interface{}) error

func (*Encoder) EncodeArrayLen added in v2.4.11

func (e *Encoder) EncodeArrayLen(l int) error

func (*Encoder) EncodeBool

func (e *Encoder) EncodeBool(value bool) error

func (*Encoder) EncodeBytes

func (e *Encoder) EncodeBytes(v []byte) error

func (*Encoder) EncodeBytesLen added in v2.8.3

func (e *Encoder) EncodeBytesLen(l int) error

func (*Encoder) EncodeFloat32

func (e *Encoder) EncodeFloat32(n float32) error

func (*Encoder) EncodeFloat64

func (e *Encoder) EncodeFloat64(n float64) error

func (*Encoder) EncodeInt

func (e *Encoder) EncodeInt(v int) error

func (*Encoder) EncodeInt16

func (e *Encoder) EncodeInt16(v int16) error

func (*Encoder) EncodeInt32

func (e *Encoder) EncodeInt32(v int32) error

func (*Encoder) EncodeInt64

func (e *Encoder) EncodeInt64(v int64) error

func (*Encoder) EncodeInt8

func (e *Encoder) EncodeInt8(v int8) error

func (*Encoder) EncodeMapLen added in v2.4.8

func (e *Encoder) EncodeMapLen(l int) error

func (*Encoder) EncodeNil

func (e *Encoder) EncodeNil() error

func (*Encoder) EncodeSliceLen

func (e *Encoder) EncodeSliceLen(l int) error

Deprecated. Use EncodeArrayLen instead.

func (*Encoder) EncodeString

func (e *Encoder) EncodeString(v string) error

func (*Encoder) EncodeTime

func (e *Encoder) EncodeTime(tm time.Time) error

func (*Encoder) EncodeUint

func (e *Encoder) EncodeUint(v uint) error

func (*Encoder) EncodeUint16

func (e *Encoder) EncodeUint16(v uint16) error

func (*Encoder) EncodeUint32

func (e *Encoder) EncodeUint32(v uint32) error

func (*Encoder) EncodeUint64

func (e *Encoder) EncodeUint64(v uint64) error

func (*Encoder) EncodeUint8

func (e *Encoder) EncodeUint8(v uint8) error

func (*Encoder) EncodeValue

func (e *Encoder) EncodeValue(v reflect.Value) error

func (*Encoder) SortMapKeys added in v2.5.3

func (e *Encoder) SortMapKeys(v bool) *Encoder

SortMapKeys causes the Encoder to encode map keys in increasing order. Supported map types are:

- map[string]string
- map[string]interface{}

func (*Encoder) StructAsArray added in v2.8.0

func (e *Encoder) StructAsArray(v bool) *Encoder

StructAsArray causes the Encoder to encode Go structs as MessagePack arrays.

Example
type Item struct {
	Foo string
	Bar string
}

var buf bytes.Buffer
enc := msgpack.NewEncoder(&buf).StructAsArray(true)
err := enc.Encode(&Item{Foo: "foo", Bar: "bar"})
if err != nil {
	panic(err)
}

dec := msgpack.NewDecoder(&buf)
v, err := dec.DecodeInterface()
if err != nil {
	panic(err)
}
fmt.Println(v)
Output:

[foo bar]

func (*Encoder) Writer added in v2.9.2

func (e *Encoder) Writer() io.Writer

Writer returns the Encoder's writer.

type Marshaler

type Marshaler interface {
	MarshalMsgpack() ([]byte, error)
}

Deprecated. Use CustomEncoder.

type Unmarshaler

type Unmarshaler interface {
	UnmarshalMsgpack([]byte) error
}

Deprecated. Use CustomDecoder.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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