pax_global_header00006660000000000000000000000064131373261650014521gustar00rootroot0000000000000052 comment=78a252b9bcb4c8b6f41c906d22c7d86fb9dfa68a msgpack-3.1.1/000077500000000000000000000000001313732616500131505ustar00rootroot00000000000000msgpack-3.1.1/.travis.yml000066400000000000000000000002061313732616500152570ustar00rootroot00000000000000sudo: false language: go go: - 1.7 - 1.8 - tip matrix: allow_failures: - go: tip install: - go get gopkg.in/check.v1 msgpack-3.1.1/CHANGELOG.md000066400000000000000000000013151313732616500147610ustar00rootroot00000000000000## v3 - gopkg.in is not supported any more. Update import path to github.com/vmihailenco/msgpack. - Msgpack maps are decoded into map[string]interface{} by default. - EncodeSliceLen is removed in favor of EncodeArrayLen. DecodeSliceLen is removed in favor of DecodeArrayLen. - Embedded structs are automatically inlined where possible. - Time is encoded using extension as described in https://github.com/msgpack/msgpack/pull/209. Old format is supported as well. - EncodeInt8/16/32/64 is replaced with EncodeInt. EncodeUint8/16/32/64 is replaced with EncodeUint. There should be no performance differences. - DecodeInterface can now return int8/16/32 and uint8/16/32. - PeekCode returns codes.Code instead of byte. msgpack-3.1.1/LICENSE000066400000000000000000000024531313732616500141610ustar00rootroot00000000000000Copyright (c) 2013 The github.com/vmihailenco/msgpack Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. msgpack-3.1.1/Makefile000066400000000000000000000001411313732616500146040ustar00rootroot00000000000000all: go test ./... env GOOS=linux GOARCH=386 go test ./... go test ./... -short -race go vet msgpack-3.1.1/README.md000066400000000000000000000050561313732616500144350ustar00rootroot00000000000000# MessagePack encoding for Golang [![Build Status](https://travis-ci.org/vmihailenco/msgpack.svg?branch=v2)](https://travis-ci.org/vmihailenco/msgpack) [![GoDoc](https://godoc.org/github.com/vmihailenco/msgpack?status.svg)](https://godoc.org/github.com/vmihailenco/msgpack) Supports: - Primitives, arrays, maps, structs, time.Time and interface{}. - Appengine *datastore.Key and datastore.Cursor. - [CustomEncoder](https://godoc.org/github.com/vmihailenco/msgpack#example-CustomEncoder)/CustomDecoder interfaces for custom encoding. - [Extensions](https://godoc.org/github.com/vmihailenco/msgpack#example-RegisterExt) to encode type information. - Renaming fields via `msgpack:"my_field_name"`. - Omitting individual empty fields via `msgpack:",omitempty"` tag or all [empty fields in a struct](https://godoc.org/github.com/vmihailenco/msgpack#example-Marshal--OmitEmpty). - [Map keys sorting](https://godoc.org/github.com/vmihailenco/msgpack#Encoder.SortMapKeys). - Encoding/decoding all [structs as arrays](https://godoc.org/github.com/vmihailenco/msgpack#Encoder.StructAsArray) or [individual structs](https://godoc.org/github.com/vmihailenco/msgpack#example-Marshal--AsArray). - Simple but very fast and efficient [queries](https://godoc.org/github.com/vmihailenco/msgpack#example-Decoder-Query). API docs: https://godoc.org/github.com/vmihailenco/msgpack. Examples: https://godoc.org/github.com/vmihailenco/msgpack#pkg-examples. ## Installation Install: ```shell go get -u github.com/vmihailenco/msgpack ``` ## Quickstart ```go 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](https://godoc.org/github.com/vmihailenco/msgpack#pkg-examples) to get an idea how to use this package. ## See also - [Golang PostgreSQL ORM](https://github.com/go-pg/pg) - [Golang message task queue](https://github.com/go-msgqueue/msgqueue) msgpack-3.1.1/appengine.go000066400000000000000000000024341313732616500154500ustar00rootroot00000000000000// +build appengine package msgpack import ( "reflect" ds "google.golang.org/appengine/datastore" ) func init() { Register((*ds.Key)(nil), encodeDatastoreKeyValue, decodeDatastoreKeyValue) Register((*ds.Cursor)(nil), encodeDatastoreCursorValue, decodeDatastoreCursorValue) } func EncodeDatastoreKey(e *Encoder, key *ds.Key) error { if key == nil { return e.EncodeNil() } return e.EncodeString(key.Encode()) } func encodeDatastoreKeyValue(e *Encoder, v reflect.Value) error { key := v.Interface().(*ds.Key) return EncodeDatastoreKey(e, key) } func DecodeDatastoreKey(d *Decoder) (*ds.Key, error) { v, err := d.DecodeString() if err != nil { return nil, err } if v == "" { return nil, nil } return ds.DecodeKey(v) } func decodeDatastoreKeyValue(d *Decoder, v reflect.Value) error { key, err := DecodeDatastoreKey(d) if err != nil { return err } v.Set(reflect.ValueOf(key)) return nil } func encodeDatastoreCursorValue(e *Encoder, v reflect.Value) error { cursor := v.Interface().(ds.Cursor) return e.Encode(cursor.String()) } func decodeDatastoreCursorValue(d *Decoder, v reflect.Value) error { s, err := d.DecodeString() if err != nil { return err } cursor, err := ds.DecodeCursor(s) if err != nil { return err } v.Set(reflect.ValueOf(cursor)) return nil } msgpack-3.1.1/bench_test.go000066400000000000000000000167701313732616500156300ustar00rootroot00000000000000package msgpack_test import ( "bytes" "encoding/binary" "encoding/csv" "encoding/gob" "encoding/json" "math" "testing" "time" "github.com/vmihailenco/msgpack" ) func benchmarkEncodeDecode(b *testing.B, src, dst interface{}) { var buf bytes.Buffer dec := msgpack.NewDecoder(&buf) enc := msgpack.NewEncoder(&buf) b.ResetTimer() for i := 0; i < b.N; i++ { if err := enc.Encode(src); err != nil { b.Fatal(err) } if err := dec.Decode(dst); err != nil { b.Fatal(err) } } } func BenchmarkBool(b *testing.B) { var dst bool benchmarkEncodeDecode(b, true, &dst) } func BenchmarkInt0(b *testing.B) { var dst int benchmarkEncodeDecode(b, 1, &dst) } func BenchmarkInt1(b *testing.B) { var dst int benchmarkEncodeDecode(b, -33, &dst) } func BenchmarkInt2(b *testing.B) { var dst int benchmarkEncodeDecode(b, 128, &dst) } func BenchmarkInt4(b *testing.B) { var dst int benchmarkEncodeDecode(b, 32768, &dst) } func BenchmarkInt8(b *testing.B) { var dst int benchmarkEncodeDecode(b, int64(2147483648), &dst) } func BenchmarkInt32(b *testing.B) { var dst int32 benchmarkEncodeDecode(b, int32(0), &dst) } func BenchmarkInt0Binary(b *testing.B) { var buf bytes.Buffer var out int32 b.ResetTimer() for i := 0; i < b.N; i++ { if err := binary.Write(&buf, binary.BigEndian, int32(1)); err != nil { b.Fatal(err) } if err := binary.Read(&buf, binary.BigEndian, &out); err != nil { b.Fatal(err) } } } func BenchmarkTime(b *testing.B) { var dst time.Time benchmarkEncodeDecode(b, time.Now(), &dst) } func BenchmarkDuration(b *testing.B) { var dst time.Duration benchmarkEncodeDecode(b, time.Hour, &dst) } func BenchmarkByteSlice(b *testing.B) { src := make([]byte, 1024) var dst []byte benchmarkEncodeDecode(b, src, &dst) } func BenchmarkByteArray(b *testing.B) { var src [1024]byte var dst [1024]byte benchmarkEncodeDecode(b, src, &dst) } func BenchmarkMapStringString(b *testing.B) { src := map[string]string{ "hello": "world", "foo": "bar", } var dst map[string]string benchmarkEncodeDecode(b, src, &dst) } func BenchmarkMapStringStringPtr(b *testing.B) { src := map[string]string{ "hello": "world", "foo": "bar", } var dst map[string]string dstptr := &dst benchmarkEncodeDecode(b, src, &dstptr) } func BenchmarkMapStringInterface(b *testing.B) { src := map[string]interface{}{ "hello": "world", "foo": "bar", } var dst map[string]interface{} benchmarkEncodeDecode(b, src, &dst) } func BenchmarkMapIntInt(b *testing.B) { src := map[int]int{ 1: 10, 2: 20, } var dst map[int]int benchmarkEncodeDecode(b, src, &dst) } func BenchmarkStringSlice(b *testing.B) { src := []string{"hello", "world"} var dst []string benchmarkEncodeDecode(b, src, &dst) } func BenchmarkStringSlicePtr(b *testing.B) { src := []string{"hello", "world"} var dst []string dstptr := &dst benchmarkEncodeDecode(b, src, &dstptr) } type benchmarkStruct struct { Name string Age int Colors []string Data []byte CreatedAt time.Time UpdatedAt time.Time } type benchmarkStruct2 struct { Name string Age int Colors []string Data []byte CreatedAt time.Time UpdatedAt time.Time } var _ msgpack.CustomEncoder = (*benchmarkStruct2)(nil) var _ msgpack.CustomDecoder = (*benchmarkStruct2)(nil) func (s *benchmarkStruct2) EncodeMsgpack(enc *msgpack.Encoder) error { return enc.Encode( s.Name, s.Colors, s.Age, s.Data, s.CreatedAt, s.UpdatedAt, ) } func (s *benchmarkStruct2) DecodeMsgpack(dec *msgpack.Decoder) error { return dec.Decode( &s.Name, &s.Colors, &s.Age, &s.Data, &s.CreatedAt, &s.UpdatedAt, ) } func structForBenchmark() *benchmarkStruct { return &benchmarkStruct{ Name: "Hello World", Colors: []string{"red", "orange", "yellow", "green", "blue", "violet"}, Age: math.MaxInt32, Data: make([]byte, 1024), CreatedAt: time.Now(), UpdatedAt: time.Now(), } } func structForBenchmark2() *benchmarkStruct2 { return &benchmarkStruct2{ Name: "Hello World", Colors: []string{"red", "orange", "yellow", "green", "blue", "violet"}, Age: math.MaxInt32, Data: make([]byte, 1024), CreatedAt: time.Now(), UpdatedAt: time.Now(), } } func BenchmarkStructVmihailencoMsgpack(b *testing.B) { in := structForBenchmark() out := new(benchmarkStruct) b.ResetTimer() for i := 0; i < b.N; i++ { buf, err := msgpack.Marshal(in) if err != nil { b.Fatal(err) } err = msgpack.Unmarshal(buf, out) if err != nil { b.Fatal(err) } } } func BenchmarkStructMarshal(b *testing.B) { in := structForBenchmark() b.ResetTimer() for i := 0; i < b.N; i++ { _, err := msgpack.Marshal(in) if err != nil { b.Fatal(err) } } } func BenchmarkStructUnmarshal(b *testing.B) { in := structForBenchmark() buf, err := msgpack.Marshal(in) if err != nil { b.Fatal(err) } out := new(benchmarkStruct) b.ResetTimer() for i := 0; i < b.N; i++ { err = msgpack.Unmarshal(buf, out) if err != nil { b.Fatal(err) } } } func BenchmarkStructManual(b *testing.B) { in := structForBenchmark2() out := new(benchmarkStruct2) b.ResetTimer() for i := 0; i < b.N; i++ { buf, err := msgpack.Marshal(in) if err != nil { b.Fatal(err) } err = msgpack.Unmarshal(buf, out) if err != nil { b.Fatal(err) } } } func BenchmarkStructJSON(b *testing.B) { in := structForBenchmark() out := new(benchmarkStruct) b.ResetTimer() for i := 0; i < b.N; i++ { buf, err := json.Marshal(in) if err != nil { b.Fatal(err) } err = json.Unmarshal(buf, out) if err != nil { b.Fatal(err) } } } func BenchmarkStructGOB(b *testing.B) { in := structForBenchmark() out := new(benchmarkStruct) b.ResetTimer() for i := 0; i < b.N; i++ { buf := new(bytes.Buffer) enc := gob.NewEncoder(buf) dec := gob.NewDecoder(buf) if err := enc.Encode(in); err != nil { b.Fatal(err) } if err := dec.Decode(out); err != nil { b.Fatal(err) } } } type benchmarkSubStruct struct { Name string Age int } func BenchmarkStructUnmarshalPartially(b *testing.B) { in := structForBenchmark() buf, err := msgpack.Marshal(in) if err != nil { b.Fatal(err) } out := &benchmarkSubStruct{} b.ResetTimer() for i := 0; i < b.N; i++ { err = msgpack.Unmarshal(buf, out) if err != nil { b.Fatal(err) } } } func BenchmarkCSV(b *testing.B) { for i := 0; i < b.N; i++ { record := []string{"1", "hello", "world"} buf := new(bytes.Buffer) r := csv.NewReader(buf) w := csv.NewWriter(buf) if err := w.Write(record); err != nil { b.Fatal(err) } w.Flush() if _, err := r.Read(); err != nil { b.Fatal(err) } } } func BenchmarkCSVMsgpack(b *testing.B) { for i := 0; i < b.N; i++ { var num int var hello, world string buf := new(bytes.Buffer) enc := msgpack.NewEncoder(buf) dec := msgpack.NewDecoder(buf) if err := enc.Encode(1, "hello", "world"); err != nil { b.Fatal(err) } if err := dec.Decode(&num, &hello, &world); err != nil { b.Fatal(err) } } } func BenchmarkQuery(b *testing.B) { var records []map[string]interface{} for i := 0; i < 1000; i++ { record := map[string]interface{}{ "id": i, "attrs": map[string]interface{}{"phone": i}, } records = append(records, record) } bs, err := msgpack.Marshal(records) if err != nil { b.Fatal(err) } dec := msgpack.NewDecoder(bytes.NewBuffer(bs)) b.ResetTimer() for i := 0; i < b.N; i++ { dec.Reset(bytes.NewBuffer(bs)) values, err := dec.Query("10.attrs.phone") if err != nil { b.Fatal(err) } if values[0].(uint64) != 10 { b.Fatalf("%v != %d", values[0], 10) } } } msgpack-3.1.1/codes/000077500000000000000000000000001313732616500142455ustar00rootroot00000000000000msgpack-3.1.1/codes/codes.go000066400000000000000000000026501313732616500156740ustar00rootroot00000000000000package codes type Code byte var ( PosFixedNumHigh Code = 0x7f NegFixedNumLow Code = 0xe0 Nil Code = 0xc0 False Code = 0xc2 True Code = 0xc3 Float Code = 0xca Double Code = 0xcb Uint8 Code = 0xcc Uint16 Code = 0xcd Uint32 Code = 0xce Uint64 Code = 0xcf Int8 Code = 0xd0 Int16 Code = 0xd1 Int32 Code = 0xd2 Int64 Code = 0xd3 FixedStrLow Code = 0xa0 FixedStrHigh Code = 0xbf FixedStrMask Code = 0x1f Str8 Code = 0xd9 Str16 Code = 0xda Str32 Code = 0xdb Bin8 Code = 0xc4 Bin16 Code = 0xc5 Bin32 Code = 0xc6 FixedArrayLow Code = 0x90 FixedArrayHigh Code = 0x9f FixedArrayMask Code = 0xf Array16 Code = 0xdc Array32 Code = 0xdd FixedMapLow Code = 0x80 FixedMapHigh Code = 0x8f FixedMapMask Code = 0xf Map16 Code = 0xde Map32 Code = 0xdf FixExt1 Code = 0xd4 FixExt2 Code = 0xd5 FixExt4 Code = 0xd6 FixExt8 Code = 0xd7 FixExt16 Code = 0xd8 Ext8 Code = 0xc7 Ext16 Code = 0xc8 Ext32 Code = 0xc9 ) func IsFixedNum(c Code) bool { return c <= PosFixedNumHigh || c >= NegFixedNumLow } func IsFixedMap(c Code) bool { return c >= FixedMapLow && c <= FixedMapHigh } func IsFixedArray(c Code) bool { return c >= FixedArrayLow && c <= FixedArrayHigh } func IsFixedString(c Code) bool { return c >= FixedStrLow && c <= FixedStrHigh } func IsExt(c Code) bool { return (c >= FixExt1 && c <= FixExt16) || (c >= Ext8 && c <= Ext32) } msgpack-3.1.1/decode.go000066400000000000000000000207231313732616500147260ustar00rootroot00000000000000package msgpack import ( "bufio" "bytes" "errors" "fmt" "io" "reflect" "time" "github.com/vmihailenco/msgpack/codes" ) const bytesAllocLimit = 1024 * 1024 // 1mb type bufReader interface { Read([]byte) (int, error) ReadByte() (byte, error) UnreadByte() error } func newBufReader(r io.Reader) bufReader { if br, ok := r.(bufReader); ok { return br } return bufio.NewReader(r) } func makeBuffer() []byte { return make([]byte, 0, 64) } // Unmarshal decodes the MessagePack-encoded data and stores the result // in the value pointed to by v. func Unmarshal(data []byte, v ...interface{}) error { return NewDecoder(bytes.NewReader(data)).Decode(v...) } type Decoder struct { r bufReader buf []byte extLen int rec []byte // accumulates read data if not nil decodeMapFunc func(*Decoder) (interface{}, error) } func NewDecoder(r io.Reader) *Decoder { return &Decoder{ decodeMapFunc: decodeMap, r: newBufReader(r), buf: makeBuffer(), } } func (d *Decoder) SetDecodeMapFunc(fn func(*Decoder) (interface{}, error)) { d.decodeMapFunc = fn } func (d *Decoder) Reset(r io.Reader) error { d.r = newBufReader(r) return nil } func (d *Decoder) Decode(v ...interface{}) error { for _, vv := range v { if err := d.decode(vv); err != nil { return err } } return nil } func (d *Decoder) decode(dst interface{}) error { var err error switch v := dst.(type) { case *string: if v != nil { *v, err = d.DecodeString() return err } case *[]byte: if v != nil { return d.decodeBytesPtr(v) } case *int: if v != nil { *v, err = d.DecodeInt() return err } case *int8: if v != nil { *v, err = d.DecodeInt8() return err } case *int16: if v != nil { *v, err = d.DecodeInt16() return err } case *int32: if v != nil { *v, err = d.DecodeInt32() return err } case *int64: if v != nil { *v, err = d.DecodeInt64() return err } case *uint: if v != nil { *v, err = d.DecodeUint() return err } case *uint8: if v != nil { *v, err = d.DecodeUint8() return err } case *uint16: if v != nil { *v, err = d.DecodeUint16() return err } case *uint32: if v != nil { *v, err = d.DecodeUint32() return err } case *uint64: if v != nil { *v, err = d.DecodeUint64() return err } case *bool: if v != nil { *v, err = d.DecodeBool() return err } case *float32: if v != nil { *v, err = d.DecodeFloat32() return err } case *float64: if v != nil { *v, err = d.DecodeFloat64() return err } case *[]string: return d.decodeStringSlicePtr(v) case *map[string]string: return d.decodeMapStringStringPtr(v) case *map[string]interface{}: return d.decodeMapStringInterfacePtr(v) case *time.Duration: if v != nil { vv, err := d.DecodeInt64() *v = time.Duration(vv) return err } case *time.Time: if v != nil { *v, err = d.DecodeTime() return err } } v := reflect.ValueOf(dst) if !v.IsValid() { return errors.New("msgpack: Decode(nil)") } if v.Kind() != reflect.Ptr { return fmt.Errorf("msgpack: Decode(nonsettable %T)", dst) } v = v.Elem() if !v.IsValid() { return fmt.Errorf("msgpack: Decode(nonsettable %T)", dst) } return d.DecodeValue(v) } func (d *Decoder) DecodeValue(v reflect.Value) error { decode := getDecoder(v.Type()) return decode(d, v) } func (d *Decoder) DecodeNil() error { c, err := d.readCode() if err != nil { return err } if c != codes.Nil { return fmt.Errorf("msgpack: invalid code=%x decoding nil", c) } return nil } func (d *Decoder) decodeNilValue(v reflect.Value) error { err := d.DecodeNil() if v.IsNil() { return err } if v.Kind() == reflect.Ptr { v = v.Elem() } v.Set(reflect.Zero(v.Type())) return err } func (d *Decoder) DecodeBool() (bool, error) { c, err := d.readCode() if err != nil { return false, err } return d.bool(c) } func (d *Decoder) bool(c codes.Code) (bool, error) { if c == codes.False { return false, nil } if c == codes.True { return true, nil } return false, fmt.Errorf("msgpack: invalid code=%x decoding bool", c) } func (d *Decoder) interfaceValue(v reflect.Value) error { vv, err := d.DecodeInterface() if err != nil { return err } if vv != nil { if v.Type() == errorType { if vv, ok := vv.(string); ok { v.Set(reflect.ValueOf(errors.New(vv))) return nil } } v.Set(reflect.ValueOf(vv)) } return nil } // DecodeInterface decodes value into interface. Possible value types are: // - nil, // - bool, // - int8, int16, int32, int64, // - uint8, uint16, uint32, uint64, // - float32 and float64, // - string, // - slices of any of the above, // - maps of any of the above. func (d *Decoder) DecodeInterface() (interface{}, error) { c, err := d.readCode() if err != nil { return nil, err } if codes.IsFixedNum(c) { return int8(c), nil } if codes.IsFixedMap(c) { d.r.UnreadByte() return d.DecodeMap() } if codes.IsFixedArray(c) { return d.decodeSlice(c) } if codes.IsFixedString(c) { return d.string(c) } switch c { case codes.Nil: return nil, nil case codes.False, codes.True: return d.bool(c) case codes.Float: return d.float32(c) case codes.Double: return d.float64(c) case codes.Uint8: return d.uint8() case codes.Uint16: return d.uint16() case codes.Uint32: return d.uint32() case codes.Uint64: return d.uint64() case codes.Int8: return d.int8() case codes.Int16: return d.int16() case codes.Int32: return d.int32() case codes.Int64: return d.int64() case codes.Bin8, codes.Bin16, codes.Bin32: return d.bytes(c, nil) case codes.Str8, codes.Str16, codes.Str32: return d.string(c) case codes.Array16, codes.Array32: return d.decodeSlice(c) case codes.Map16, codes.Map32: d.r.UnreadByte() return d.DecodeMap() case codes.FixExt1, codes.FixExt2, codes.FixExt4, codes.FixExt8, codes.FixExt16, codes.Ext8, codes.Ext16, codes.Ext32: return d.ext(c) } return 0, fmt.Errorf("msgpack: unknown code %x decoding interface{}", c) } // Skip skips next value. func (d *Decoder) Skip() error { c, err := d.readCode() if err != nil { return err } if codes.IsFixedNum(c) { return nil } else if codes.IsFixedMap(c) { return d.skipMap(c) } else if codes.IsFixedArray(c) { return d.skipSlice(c) } else if codes.IsFixedString(c) { return d.skipBytes(c) } switch c { case codes.Nil, codes.False, codes.True: return nil case codes.Uint8, codes.Int8: return d.skipN(1) case codes.Uint16, codes.Int16: return d.skipN(2) case codes.Uint32, codes.Int32, codes.Float: return d.skipN(4) case codes.Uint64, codes.Int64, codes.Double: return d.skipN(8) case codes.Bin8, codes.Bin16, codes.Bin32: return d.skipBytes(c) case codes.Str8, codes.Str16, codes.Str32: return d.skipBytes(c) case codes.Array16, codes.Array32: return d.skipSlice(c) case codes.Map16, codes.Map32: return d.skipMap(c) case codes.FixExt1, codes.FixExt2, codes.FixExt4, codes.FixExt8, codes.FixExt16, codes.Ext8, codes.Ext16, codes.Ext32: return d.skipExt(c) } return fmt.Errorf("msgpack: unknown code %x", c) } // PeekCode returns the next MessagePack code without advancing the reader. // Subpackage msgpack/codes contains list of available codes. func (d *Decoder) PeekCode() (codes.Code, error) { c, err := d.r.ReadByte() if err != nil { return 0, err } return codes.Code(c), d.r.UnreadByte() } func (d *Decoder) hasNilCode() bool { code, err := d.PeekCode() return err == nil && code == codes.Nil } func (d *Decoder) readCode() (codes.Code, error) { c, err := d.r.ReadByte() if err != nil { return 0, err } if d.rec != nil { d.rec = append(d.rec, c) } return codes.Code(c), nil } func (d *Decoder) readFull(b []byte) error { _, err := io.ReadFull(d.r, b) if err != nil { return err } if d.rec != nil { d.rec = append(d.rec, b...) } return nil } func (d *Decoder) readN(n int) ([]byte, error) { buf, err := readN(d.r, d.buf, n) if err != nil { return nil, err } d.buf = buf if d.rec != nil { d.rec = append(d.rec, buf...) } return buf, nil } func readN(r io.Reader, b []byte, n int) ([]byte, error) { if n == 0 && b == nil { return make([]byte, 0), nil } if cap(b) >= n { b = b[:n] _, err := io.ReadFull(r, b) return b, err } b = b[:cap(b)] var pos int for len(b) < n { diff := n - len(b) if diff > bytesAllocLimit { diff = bytesAllocLimit } b = append(b, make([]byte, diff)...) _, err := io.ReadFull(r, b[pos:]) if err != nil { return nil, err } pos = len(b) } return b, nil } func min(a, b int) int { if a <= b { return a } return b } msgpack-3.1.1/decode_map.go000066400000000000000000000112211313732616500155540ustar00rootroot00000000000000package msgpack import ( "fmt" "reflect" "github.com/vmihailenco/msgpack/codes" ) const mapElemsAllocLimit = 1e4 var mapStringStringPtrType = reflect.TypeOf((*map[string]string)(nil)) var mapStringStringType = mapStringStringPtrType.Elem() var mapStringInterfacePtrType = reflect.TypeOf((*map[string]interface{})(nil)) var mapStringInterfaceType = mapStringInterfacePtrType.Elem() func decodeMapValue(d *Decoder, v reflect.Value) error { n, err := d.DecodeMapLen() if err != nil { return err } typ := v.Type() if n == -1 { v.Set(reflect.Zero(typ)) return nil } if v.IsNil() { v.Set(reflect.MakeMap(typ)) } keyType := typ.Key() valueType := typ.Elem() for i := 0; i < n; i++ { mk := reflect.New(keyType).Elem() if err := d.DecodeValue(mk); err != nil { return err } mv := reflect.New(valueType).Elem() if err := d.DecodeValue(mv); err != nil { return err } v.SetMapIndex(mk, mv) } return nil } func decodeMap(d *Decoder) (interface{}, error) { n, err := d.DecodeMapLen() if err != nil { return nil, err } if n == -1 { return nil, nil } m := make(map[string]interface{}, min(n, mapElemsAllocLimit)) 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 } func (d *Decoder) DecodeMapLen() (int, error) { c, err := d.readCode() if err != nil { return 0, err } if codes.IsExt(c) { if err = d.skipExtHeader(c); err != nil { return 0, err } c, err = d.readCode() if err != nil { return 0, err } } return d.mapLen(c) } func (d *Decoder) mapLen(c codes.Code) (int, error) { if c == codes.Nil { return -1, nil } if c >= codes.FixedMapLow && c <= codes.FixedMapHigh { return int(c & codes.FixedMapMask), nil } if c == codes.Map16 { n, err := d.uint16() return int(n), err } if c == codes.Map32 { n, err := d.uint32() return int(n), err } return 0, fmt.Errorf("msgpack: invalid code=%x decoding map length", c) } func decodeMapStringStringValue(d *Decoder, v reflect.Value) error { mptr := v.Addr().Convert(mapStringStringPtrType).Interface().(*map[string]string) return d.decodeMapStringStringPtr(mptr) } func (d *Decoder) decodeMapStringStringPtr(ptr *map[string]string) error { n, err := d.DecodeMapLen() if err != nil { return err } if n == -1 { *ptr = nil return nil } m := *ptr if m == nil { *ptr = make(map[string]string, min(n, mapElemsAllocLimit)) m = *ptr } for i := 0; i < n; i++ { mk, err := d.DecodeString() if err != nil { return err } mv, err := d.DecodeString() if err != nil { return err } m[mk] = mv } return nil } func decodeMapStringInterfaceValue(d *Decoder, v reflect.Value) error { ptr := v.Addr().Convert(mapStringInterfacePtrType).Interface().(*map[string]interface{}) return d.decodeMapStringInterfacePtr(ptr) } func (d *Decoder) decodeMapStringInterfacePtr(ptr *map[string]interface{}) error { n, err := d.DecodeMapLen() if err != nil { return err } if n == -1 { *ptr = nil return nil } m := *ptr if m == nil { *ptr = make(map[string]interface{}, min(n, mapElemsAllocLimit)) m = *ptr } for i := 0; i < n; i++ { mk, err := d.DecodeString() if err != nil { return err } mv, err := d.DecodeInterface() if err != nil { return err } m[mk] = mv } return nil } func (d *Decoder) DecodeMap() (interface{}, error) { return d.decodeMapFunc(d) } func (d *Decoder) skipMap(c codes.Code) error { n, err := d.mapLen(c) if err != nil { return err } for i := 0; i < n; i++ { if err := d.Skip(); err != nil { return err } if err := d.Skip(); err != nil { return err } } return nil } func decodeStructValue(d *Decoder, strct reflect.Value) error { c, err := d.readCode() if err != nil { return err } var isArray bool n, err := d.mapLen(c) if err != nil { var err2 error n, err2 = d.arrayLen(c) if err2 != nil { return err } isArray = true } if n == -1 { strct.Set(reflect.Zero(strct.Type())) return nil } fields := structs.Fields(strct.Type()) if isArray { for i, f := range fields.List { if i >= n { break } if err := f.DecodeValue(d, strct); err != nil { return err } } // Skip extra values. for i := len(fields.List); i < n; i++ { if err := d.Skip(); err != nil { return err } } return nil } for i := 0; i < n; i++ { name, err := d.DecodeString() if err != nil { return err } if f := fields.Table[name]; f != nil { if err := f.DecodeValue(d, strct); err != nil { return err } } else { if err := d.Skip(); err != nil { return err } } } return nil } msgpack-3.1.1/decode_number.go000066400000000000000000000125321313732616500162750ustar00rootroot00000000000000package msgpack import ( "fmt" "math" "reflect" "github.com/vmihailenco/msgpack/codes" ) func (d *Decoder) skipN(n int) error { _, err := d.readN(n) return err } func (d *Decoder) uint8() (uint8, error) { c, err := d.readCode() if err != nil { return 0, err } return uint8(c), nil } func (d *Decoder) int8() (int8, error) { n, err := d.uint8() return int8(n), err } func (d *Decoder) uint16() (uint16, error) { b, err := d.readN(2) if err != nil { return 0, err } return (uint16(b[0]) << 8) | uint16(b[1]), nil } func (d *Decoder) int16() (int16, error) { n, err := d.uint16() return int16(n), err } func (d *Decoder) uint32() (uint32, error) { b, err := d.readN(4) if err != nil { return 0, err } n := (uint32(b[0]) << 24) | (uint32(b[1]) << 16) | (uint32(b[2]) << 8) | uint32(b[3]) return n, nil } func (d *Decoder) int32() (int32, error) { n, err := d.uint32() return int32(n), err } func (d *Decoder) uint64() (uint64, error) { b, err := d.readN(8) if err != nil { return 0, err } n := (uint64(b[0]) << 56) | (uint64(b[1]) << 48) | (uint64(b[2]) << 40) | (uint64(b[3]) << 32) | (uint64(b[4]) << 24) | (uint64(b[5]) << 16) | (uint64(b[6]) << 8) | uint64(b[7]) return n, nil } func (d *Decoder) int64() (int64, error) { n, err := d.uint64() return int64(n), err } func (d *Decoder) DecodeUint64() (uint64, error) { c, err := d.readCode() if err != nil { return 0, err } return d.uint(c) } func (d *Decoder) uint(c codes.Code) (uint64, error) { if c == codes.Nil { return 0, nil } if codes.IsFixedNum(c) { return uint64(int8(c)), nil } switch c { case codes.Uint8: n, err := d.uint8() return uint64(n), err case codes.Int8: n, err := d.int8() return uint64(n), err case codes.Uint16: n, err := d.uint16() return uint64(n), err case codes.Int16: n, err := d.int16() return uint64(n), err case codes.Uint32: n, err := d.uint32() return uint64(n), err case codes.Int32: n, err := d.int32() return uint64(n), err case codes.Uint64, codes.Int64: return d.uint64() } return 0, fmt.Errorf("msgpack: invalid code=%x decoding uint64", c) } func (d *Decoder) DecodeInt64() (int64, error) { c, err := d.readCode() if err != nil { return 0, err } return d.int(c) } func (d *Decoder) int(c codes.Code) (int64, error) { if c == codes.Nil { return 0, nil } if codes.IsFixedNum(c) { return int64(int8(c)), nil } switch c { case codes.Uint8: n, err := d.uint8() return int64(n), err case codes.Int8: n, err := d.uint8() return int64(int8(n)), err case codes.Uint16: n, err := d.uint16() return int64(n), err case codes.Int16: n, err := d.uint16() return int64(int16(n)), err case codes.Uint32: n, err := d.uint32() return int64(n), err case codes.Int32: n, err := d.uint32() return int64(int32(n)), err case codes.Uint64, codes.Int64: n, err := d.uint64() return int64(n), err } return 0, fmt.Errorf("msgpack: invalid code=%x decoding int64", c) } func (d *Decoder) DecodeFloat32() (float32, error) { c, err := d.readCode() if err != nil { return 0, err } return d.float32(c) } func (d *Decoder) float32(c codes.Code) (float32, error) { if c == codes.Float { n, err := d.uint32() if err != nil { return 0, err } return math.Float32frombits(n), nil } n, err := d.int(c) if err != nil { return 0, fmt.Errorf("msgpack: invalid code=%x decoding float32", c) } return float32(n), nil } func (d *Decoder) DecodeFloat64() (float64, error) { c, err := d.readCode() if err != nil { return 0, err } return d.float64(c) } func (d *Decoder) float64(c codes.Code) (float64, error) { switch c { case codes.Float: n, err := d.float32(c) if err != nil { return 0, err } return float64(n), nil case codes.Double: n, err := d.uint64() if err != nil { return 0, err } return math.Float64frombits(n), nil } n, err := d.int(c) if err != nil { return 0, fmt.Errorf("msgpack: invalid code=%x decoding float32", c) } return float64(n), nil } func (d *Decoder) DecodeUint() (uint, error) { n, err := d.DecodeUint64() return uint(n), err } func (d *Decoder) DecodeUint8() (uint8, error) { n, err := d.DecodeUint64() return uint8(n), err } func (d *Decoder) DecodeUint16() (uint16, error) { n, err := d.DecodeUint64() return uint16(n), err } func (d *Decoder) DecodeUint32() (uint32, error) { n, err := d.DecodeUint64() return uint32(n), err } func (d *Decoder) DecodeInt() (int, error) { n, err := d.DecodeInt64() return int(n), err } func (d *Decoder) DecodeInt8() (int8, error) { n, err := d.DecodeInt64() return int8(n), err } func (d *Decoder) DecodeInt16() (int16, error) { n, err := d.DecodeInt64() return int16(n), err } func (d *Decoder) DecodeInt32() (int32, error) { n, err := d.DecodeInt64() return int32(n), err } func decodeFloat32Value(d *Decoder, v reflect.Value) error { f, err := d.DecodeFloat32() if err != nil { return err } v.SetFloat(float64(f)) return nil } func decodeFloat64Value(d *Decoder, v reflect.Value) error { f, err := d.DecodeFloat64() if err != nil { return err } v.SetFloat(f) return nil } func decodeInt64Value(d *Decoder, v reflect.Value) error { n, err := d.DecodeInt64() if err != nil { return err } v.SetInt(n) return nil } func decodeUint64Value(d *Decoder, v reflect.Value) error { n, err := d.DecodeUint64() if err != nil { return err } v.SetUint(n) return nil } msgpack-3.1.1/decode_query.go000066400000000000000000000051411313732616500161500ustar00rootroot00000000000000package msgpack import ( "fmt" "strconv" "strings" "github.com/vmihailenco/msgpack/codes" ) type queryResult struct { query string key string hasAsterisk bool values []interface{} } func (q *queryResult) nextKey() { ind := strings.IndexByte(q.query, '.') if ind == -1 { q.key = q.query q.query = "" return } q.key = q.query[:ind] q.query = q.query[ind+1:] } // 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. func (d *Decoder) Query(query string) ([]interface{}, error) { res := queryResult{ query: query, } if err := d.query(&res); err != nil { return nil, err } return res.values, nil } func (d *Decoder) query(q *queryResult) error { q.nextKey() if q.key == "" { v, err := d.DecodeInterface() if err != nil { return err } q.values = append(q.values, v) return nil } code, err := d.PeekCode() if err != nil { return err } switch { case code == codes.Map16 || code == codes.Map32 || codes.IsFixedMap(code): err = d.queryMapKey(q) case code == codes.Array16 || code == codes.Array32 || codes.IsFixedArray(code): err = d.queryArrayIndex(q) default: err = fmt.Errorf("msgpack: unsupported code=%x decoding key=%q", code, q.key) } return err } func (d *Decoder) queryMapKey(q *queryResult) error { n, err := d.DecodeMapLen() if err != nil { return err } if n == -1 { return nil } for i := 0; i < n; i++ { k, err := d.bytesNoCopy() if err != nil { return err } if string(k) == q.key { if err := d.query(q); err != nil { return err } if q.hasAsterisk { return d.skipNext((n - i - 1) * 2) } return nil } if err := d.Skip(); err != nil { return err } } return nil } func (d *Decoder) queryArrayIndex(q *queryResult) error { n, err := d.DecodeArrayLen() if err != nil { return err } if n == -1 { return nil } if q.key == "*" { q.hasAsterisk = true query := q.query for i := 0; i < n; i++ { q.query = query if err := d.query(q); err != nil { return err } } q.hasAsterisk = false return nil } ind, err := strconv.Atoi(q.key) if err != nil { return err } for i := 0; i < n; i++ { if i == ind { if err := d.query(q); err != nil { return err } if q.hasAsterisk { return d.skipNext(n - i - 1) } return nil } if err := d.Skip(); err != nil { return err } } return nil } func (d *Decoder) skipNext(n int) error { for i := 0; i < n; i++ { if err := d.Skip(); err != nil { return err } } return nil } msgpack-3.1.1/decode_slice.go000066400000000000000000000065321313732616500161070ustar00rootroot00000000000000package msgpack import ( "fmt" "reflect" "github.com/vmihailenco/msgpack/codes" ) const sliceElemsAllocLimit = 1e4 var sliceStringPtrType = reflect.TypeOf((*[]string)(nil)) func (d *Decoder) DecodeArrayLen() (int, error) { c, err := d.readCode() if err != nil { return 0, err } return d.arrayLen(c) } func (d *Decoder) arrayLen(c codes.Code) (int, error) { if c == codes.Nil { return -1, nil } else if c >= codes.FixedArrayLow && c <= codes.FixedArrayHigh { return int(c & codes.FixedArrayMask), nil } switch c { case codes.Array16: n, err := d.uint16() return int(n), err case codes.Array32: n, err := d.uint32() return int(n), err } return 0, fmt.Errorf("msgpack: invalid code=%x decoding array length", c) } func decodeStringSliceValue(d *Decoder, v reflect.Value) error { ptr := v.Addr().Convert(sliceStringPtrType).Interface().(*[]string) return d.decodeStringSlicePtr(ptr) } func (d *Decoder) decodeStringSlicePtr(ptr *[]string) error { n, err := d.DecodeArrayLen() if err != nil { return err } if n == -1 { return nil } ss := setStringsCap(*ptr, n) for i := 0; i < n; i++ { s, err := d.DecodeString() if err != nil { return err } ss = append(ss, s) } *ptr = ss return nil } func setStringsCap(s []string, n int) []string { if n > sliceElemsAllocLimit { n = sliceElemsAllocLimit } if s == nil { return make([]string, 0, n) } if cap(s) >= n { return s[:0] } s = s[:cap(s)] s = append(s, make([]string, n-len(s))...) return s[:0] } func decodeSliceValue(d *Decoder, v reflect.Value) error { n, err := d.DecodeArrayLen() if err != nil { return err } if n == -1 { v.Set(reflect.Zero(v.Type())) return nil } if n == 0 && v.IsNil() { v.Set(reflect.MakeSlice(v.Type(), 0, 0)) return nil } if v.Cap() >= n { v.Set(v.Slice(0, n)) } else if v.Len() < v.Cap() { v.Set(v.Slice(0, v.Cap())) } for i := 0; i < n; i++ { if i >= v.Len() { v.Set(growSliceValue(v, n)) } sv := v.Index(i) if err := d.DecodeValue(sv); err != nil { return err } } return nil } func growSliceValue(v reflect.Value, n int) reflect.Value { diff := n - v.Len() if diff > sliceElemsAllocLimit { diff = sliceElemsAllocLimit } v = reflect.AppendSlice(v, reflect.MakeSlice(v.Type(), diff, diff)) return v } func decodeArrayValue(d *Decoder, v reflect.Value) error { n, err := d.DecodeArrayLen() if err != nil { return err } if n == -1 { return nil } if n > v.Len() { return fmt.Errorf("%s len is %d, but msgpack has %d elements", v.Type(), v.Len(), n) } for i := 0; i < n; i++ { sv := v.Index(i) if err := d.DecodeValue(sv); err != nil { return err } } return nil } func (d *Decoder) DecodeSlice() ([]interface{}, error) { c, err := d.readCode() if err != nil { return nil, err } return d.decodeSlice(c) } func (d *Decoder) decodeSlice(c codes.Code) ([]interface{}, error) { n, err := d.arrayLen(c) if err != nil { return nil, err } if n == -1 { return nil, nil } s := make([]interface{}, 0, min(n, sliceElemsAllocLimit)) for i := 0; i < n; i++ { v, err := d.DecodeInterface() if err != nil { return nil, err } s = append(s, v) } return s, nil } func (d *Decoder) skipSlice(c codes.Code) error { n, err := d.arrayLen(c) if err != nil { return err } for i := 0; i < n; i++ { if err := d.Skip(); err != nil { return err } } return nil } msgpack-3.1.1/decode_string.go000066400000000000000000000054601313732616500163150ustar00rootroot00000000000000package msgpack import ( "fmt" "reflect" "github.com/vmihailenco/msgpack/codes" ) func (d *Decoder) bytesLen(c codes.Code) (int, error) { if c == codes.Nil { return -1, nil } else if codes.IsFixedString(c) { return int(c & codes.FixedStrMask), nil } switch c { case codes.Str8, codes.Bin8: n, err := d.uint8() return int(n), err case codes.Str16, codes.Bin16: n, err := d.uint16() return int(n), err case codes.Str32, codes.Bin32: n, err := d.uint32() return int(n), err } return 0, fmt.Errorf("msgpack: invalid code=%x decoding bytes length", c) } func (d *Decoder) DecodeString() (string, error) { c, err := d.readCode() if err != nil { return "", err } return d.string(c) } func (d *Decoder) string(c codes.Code) (string, error) { n, err := d.bytesLen(c) if err != nil { return "", err } if n == -1 { return "", nil } b, err := d.readN(n) return string(b), err } func decodeStringValue(d *Decoder, v reflect.Value) error { s, err := d.DecodeString() if err != nil { return err } v.SetString(s) return nil } func (d *Decoder) DecodeBytesLen() (int, error) { c, err := d.readCode() if err != nil { return 0, err } return d.bytesLen(c) } func (d *Decoder) DecodeBytes() ([]byte, error) { c, err := d.readCode() if err != nil { return nil, err } return d.bytes(c, nil) } func (d *Decoder) bytes(c codes.Code, b []byte) ([]byte, error) { n, err := d.bytesLen(c) if err != nil { return nil, err } if n == -1 { return nil, nil } return readN(d.r, b, n) } func (d *Decoder) bytesNoCopy() ([]byte, error) { c, err := d.readCode() if err != nil { return nil, err } n, err := d.bytesLen(c) if err != nil { return nil, err } if n == -1 { return nil, nil } return d.readN(n) } func (d *Decoder) decodeBytesPtr(ptr *[]byte) error { c, err := d.readCode() if err != nil { return err } return d.bytesPtr(c, ptr) } func (d *Decoder) bytesPtr(c codes.Code, ptr *[]byte) error { n, err := d.bytesLen(c) if err != nil { return err } if n == -1 { *ptr = nil return nil } *ptr, err = readN(d.r, *ptr, n) return err } func (d *Decoder) skipBytes(c codes.Code) error { n, err := d.bytesLen(c) if err != nil { return err } if n == -1 { return nil } return d.skipN(n) } func decodeBytesValue(d *Decoder, v reflect.Value) error { c, err := d.readCode() if err != nil { return err } b, err := d.bytes(c, v.Bytes()) if err != nil { return err } v.SetBytes(b) return nil } func decodeByteArrayValue(d *Decoder, v reflect.Value) error { c, err := d.readCode() if err != nil { return err } n, err := d.bytesLen(c) if err != nil { return err } if n == -1 { return nil } if n > v.Len() { return fmt.Errorf("%s len is %d, but msgpack has %d elements", v.Type(), v.Len(), n) } b := v.Slice(0, n).Bytes() return d.readFull(b) } msgpack-3.1.1/decode_value.go000066400000000000000000000120601313732616500161150ustar00rootroot00000000000000package msgpack import ( "fmt" "reflect" "github.com/vmihailenco/msgpack/codes" ) var interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() var stringType = reflect.TypeOf((*string)(nil)).Elem() var valueDecoders []decoderFunc func init() { valueDecoders = []decoderFunc{ reflect.Bool: decodeBoolValue, reflect.Int: decodeInt64Value, reflect.Int8: decodeInt64Value, reflect.Int16: decodeInt64Value, reflect.Int32: decodeInt64Value, reflect.Int64: decodeInt64Value, reflect.Uint: decodeUint64Value, reflect.Uint8: decodeUint64Value, reflect.Uint16: decodeUint64Value, reflect.Uint32: decodeUint64Value, reflect.Uint64: decodeUint64Value, reflect.Float32: decodeFloat32Value, reflect.Float64: decodeFloat64Value, reflect.Complex64: decodeUnsupportedValue, reflect.Complex128: decodeUnsupportedValue, reflect.Array: decodeArrayValue, reflect.Chan: decodeUnsupportedValue, reflect.Func: decodeUnsupportedValue, reflect.Interface: decodeInterfaceValue, reflect.Map: decodeMapValue, reflect.Ptr: decodeUnsupportedValue, reflect.Slice: decodeSliceValue, reflect.String: decodeStringValue, reflect.Struct: decodeStructValue, reflect.UnsafePointer: decodeUnsupportedValue, } } func getDecoder(typ reflect.Type) decoderFunc { kind := typ.Kind() if decoder, ok := typDecMap[typ]; ok { return decoder } if typ.Implements(customDecoderType) { return decodeCustomValue } if typ.Implements(unmarshalerType) { return unmarshalValue } // Addressable struct field value. if kind != reflect.Ptr { ptr := reflect.PtrTo(typ) if ptr.Implements(customDecoderType) { return decodeCustomValueAddr } if ptr.Implements(unmarshalerType) { return unmarshalValueAddr } } switch kind { case reflect.Ptr: return ptrDecoderFunc(typ) case reflect.Slice: elem := typ.Elem() switch elem.Kind() { case reflect.Uint8: return decodeBytesValue } switch elem { case stringType: return decodeStringSliceValue } case reflect.Array: if typ.Elem().Kind() == reflect.Uint8 { return decodeByteArrayValue } case reflect.Map: if typ.Key() == stringType { switch typ.Elem() { case stringType: return decodeMapStringStringValue case interfaceType: return decodeMapStringInterfaceValue } } } return valueDecoders[kind] } func ptrDecoderFunc(typ reflect.Type) decoderFunc { decoder := getDecoder(typ.Elem()) return func(d *Decoder, v reflect.Value) error { if d.hasNilCode() { v.Set(reflect.Zero(v.Type())) return d.DecodeNil() } if v.IsNil() { if !v.CanSet() { return fmt.Errorf("msgpack: Decode(nonsettable %T)", v.Interface()) } v.Set(reflect.New(v.Type().Elem())) } return decoder(d, v.Elem()) } } func decodeCustomValueAddr(d *Decoder, v reflect.Value) error { if !v.CanAddr() { return fmt.Errorf("msgpack: Decode(nonsettable %T)", v.Interface()) } return decodeCustomValue(d, v.Addr()) } func decodeCustomValue(d *Decoder, v reflect.Value) error { c, err := d.PeekCode() if err != nil { return err } if codes.IsExt(c) { c, err = d.readCode() if err != nil { return err } _, err = d.parseExtLen(c) if err != nil { return err } _, err = d.readCode() if err != nil { return err } c, err = d.PeekCode() if err != nil { return err } } if c == codes.Nil { return d.decodeNilValue(v) } if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) } decoder := v.Interface().(CustomDecoder) return decoder.DecodeMsgpack(d) } func unmarshalValueAddr(d *Decoder, v reflect.Value) error { if !v.CanAddr() { return fmt.Errorf("msgpack: Decode(nonsettable %T)", v.Interface()) } return unmarshalValue(d, v.Addr()) } func unmarshalValue(d *Decoder, v reflect.Value) error { c, err := d.PeekCode() if err != nil { return err } if codes.IsExt(c) { c, err = d.readCode() if err != nil { return err } extLen, err := d.parseExtLen(c) if err != nil { return err } d.extLen = extLen _, err = d.readCode() if err != nil { return err } c, err = d.PeekCode() if err != nil { return err } } if c == codes.Nil { return d.decodeNilValue(v) } if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) } if d.extLen != 0 { b, err := d.readN(d.extLen) d.extLen = 0 if err != nil { return err } d.rec = b } else { d.rec = makeBuffer() if err := d.Skip(); err != nil { return err } } unmarshaler := v.Interface().(Unmarshaler) err = unmarshaler.UnmarshalMsgpack(d.rec) d.rec = nil return err } func decodeBoolValue(d *Decoder, v reflect.Value) error { flag, err := d.DecodeBool() if err != nil { return err } v.SetBool(flag) return nil } func decodeInterfaceValue(d *Decoder, v reflect.Value) error { if v.IsNil() { return d.interfaceValue(v) } return d.DecodeValue(v.Elem()) } func decodeUnsupportedValue(d *Decoder, v reflect.Value) error { return fmt.Errorf("msgpack: Decode(unsupported %s)", v.Type()) } msgpack-3.1.1/encode.go000066400000000000000000000050451313732616500147400ustar00rootroot00000000000000package msgpack import ( "bytes" "io" "reflect" "time" "github.com/vmihailenco/msgpack/codes" ) type writer interface { io.Writer WriteByte(byte) error WriteString(string) (int, error) } type byteWriter struct { io.Writer } func (w byteWriter) WriteByte(b byte) error { _, err := w.Write([]byte{b}) return err } func (w byteWriter) WriteString(s string) (int, error) { return w.Write([]byte(s)) } // Marshal returns the MessagePack encoding of v. func Marshal(v ...interface{}) ([]byte, error) { var buf bytes.Buffer err := NewEncoder(&buf).Encode(v...) return buf.Bytes(), err } type Encoder struct { w writer buf []byte sortMapKeys bool structAsArray bool } func NewEncoder(w io.Writer) *Encoder { bw, ok := w.(writer) if !ok { bw = byteWriter{Writer: w} } return &Encoder{ w: bw, buf: make([]byte, 9), } } // SortMapKeys causes the Encoder to encode map keys in increasing order. // Supported map types are: // - map[string]string // - map[string]interface{} func (e *Encoder) SortMapKeys(v bool) *Encoder { e.sortMapKeys = v return e } // StructAsArray causes the Encoder to encode Go structs as MessagePack arrays. func (e *Encoder) StructAsArray(v bool) *Encoder { e.structAsArray = v return e } func (e *Encoder) Encode(v ...interface{}) error { for _, vv := range v { if err := e.encode(vv); err != nil { return err } } return nil } func (e *Encoder) encode(v interface{}) error { switch v := v.(type) { case nil: return e.EncodeNil() case string: return e.EncodeString(v) case []byte: return e.EncodeBytes(v) case int: return e.EncodeInt(int64(v)) case int64: return e.EncodeInt(v) case uint: return e.EncodeUint(uint64(v)) case uint64: return e.EncodeUint(v) case bool: return e.EncodeBool(v) case float32: return e.EncodeFloat32(v) case float64: return e.EncodeFloat64(v) case time.Duration: return e.EncodeInt(int64(v)) case time.Time: return e.EncodeTime(v) } return e.EncodeValue(reflect.ValueOf(v)) } func (e *Encoder) EncodeValue(v reflect.Value) error { encode := getEncoder(v.Type()) return encode(e, v) } func (e *Encoder) EncodeNil() error { return e.writeCode(codes.Nil) } func (e *Encoder) EncodeBool(value bool) error { if value { return e.writeCode(codes.True) } return e.writeCode(codes.False) } func (e *Encoder) writeCode(c codes.Code) error { return e.w.WriteByte(byte(c)) } func (e *Encoder) write(b []byte) error { _, err := e.w.Write(b) return err } func (e *Encoder) writeString(s string) error { _, err := e.w.WriteString(s) return err } msgpack-3.1.1/encode_map.go000066400000000000000000000061061313732616500155740ustar00rootroot00000000000000package msgpack import ( "reflect" "sort" "github.com/vmihailenco/msgpack/codes" ) func encodeMapValue(e *Encoder, v reflect.Value) error { if v.IsNil() { return e.EncodeNil() } if err := e.EncodeMapLen(v.Len()); err != nil { return err } for _, key := range v.MapKeys() { if err := e.EncodeValue(key); err != nil { return err } if err := e.EncodeValue(v.MapIndex(key)); err != nil { return err } } return nil } func encodeMapStringStringValue(e *Encoder, v reflect.Value) error { if v.IsNil() { return e.EncodeNil() } if err := e.EncodeMapLen(v.Len()); err != nil { return err } m := v.Convert(mapStringStringType).Interface().(map[string]string) if e.sortMapKeys { return e.encodeSortedMapStringString(m) } for mk, mv := range m { if err := e.EncodeString(mk); err != nil { return err } if err := e.EncodeString(mv); err != nil { return err } } return nil } func encodeMapStringInterfaceValue(e *Encoder, v reflect.Value) error { if v.IsNil() { return e.EncodeNil() } if err := e.EncodeMapLen(v.Len()); err != nil { return err } m := v.Convert(mapStringInterfaceType).Interface().(map[string]interface{}) if e.sortMapKeys { return e.encodeSortedMapStringInterface(m) } for mk, mv := range m { if err := e.EncodeString(mk); err != nil { return err } if err := e.Encode(mv); err != nil { return err } } return nil } func (e *Encoder) encodeSortedMapStringString(m map[string]string) error { keys := make([]string, 0, len(m)) for k, _ := range m { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { err := e.EncodeString(k) if err != nil { return err } if err = e.EncodeString(m[k]); err != nil { return err } } return nil } func (e *Encoder) encodeSortedMapStringInterface(m map[string]interface{}) error { keys := make([]string, 0, len(m)) for k, _ := range m { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { err := e.EncodeString(k) if err != nil { return err } if err = e.Encode(m[k]); err != nil { return err } } return nil } func (e *Encoder) EncodeMapLen(l int) error { if l < 16 { return e.writeCode(codes.FixedMapLow | codes.Code(l)) } if l < 65536 { return e.write2(codes.Map16, uint64(l)) } return e.write4(codes.Map32, uint32(l)) } func encodeStructValue(e *Encoder, strct reflect.Value) error { structFields := structs.Fields(strct.Type()) if e.structAsArray || structFields.asArray { return encodeStructValueAsArray(e, strct, structFields.List) } fields := structFields.OmitEmpty(strct) if err := e.EncodeMapLen(len(fields)); err != nil { return err } for _, f := range fields { if err := e.EncodeString(f.name); err != nil { return err } if err := f.EncodeValue(e, strct); err != nil { return err } } return nil } func encodeStructValueAsArray(e *Encoder, strct reflect.Value, fields []*field) error { if err := e.EncodeArrayLen(len(fields)); err != nil { return err } for _, f := range fields { if err := f.EncodeValue(e, strct); err != nil { return err } } return nil } msgpack-3.1.1/encode_number.go000066400000000000000000000046211313732616500163070ustar00rootroot00000000000000package msgpack import ( "math" "reflect" "github.com/vmihailenco/msgpack/codes" ) // EncodeUint encodes an uint64 in 1, 2, 3, 5, or 9 bytes. func (e *Encoder) EncodeUint(v uint64) error { if v <= math.MaxInt8 { return e.w.WriteByte(byte(v)) } if v <= math.MaxUint8 { return e.write1(codes.Uint8, v) } if v <= math.MaxUint16 { return e.write2(codes.Uint16, v) } if v <= math.MaxUint32 { return e.write4(codes.Uint32, uint32(v)) } return e.write8(codes.Uint64, v) } // EncodeInt encodes an int64 in 1, 2, 3, 5, or 9 bytes. func (e *Encoder) EncodeInt(v int64) error { if v >= 0 { return e.EncodeUint(uint64(v)) } if v >= int64(int8(codes.NegFixedNumLow)) { return e.w.WriteByte(byte(v)) } if v >= math.MinInt8 { return e.write1(codes.Int8, uint64(v)) } if v >= math.MinInt16 { return e.write2(codes.Int16, uint64(v)) } if v >= math.MinInt32 { return e.write4(codes.Int32, uint32(v)) } return e.write8(codes.Int64, uint64(v)) } func (e *Encoder) EncodeFloat32(n float32) error { return e.write4(codes.Float, math.Float32bits(n)) } func (e *Encoder) EncodeFloat64(n float64) error { return e.write8(codes.Double, math.Float64bits(n)) } func (e *Encoder) write1(code codes.Code, n uint64) error { e.buf = e.buf[:2] e.buf[0] = byte(code) e.buf[1] = byte(n) return e.write(e.buf) } func (e *Encoder) write2(code codes.Code, n uint64) error { e.buf = e.buf[:3] e.buf[0] = byte(code) e.buf[1] = byte(n >> 8) e.buf[2] = byte(n) return e.write(e.buf) } func (e *Encoder) write4(code codes.Code, n uint32) error { e.buf = e.buf[:5] e.buf[0] = byte(code) e.buf[1] = byte(n >> 24) e.buf[2] = byte(n >> 16) e.buf[3] = byte(n >> 8) e.buf[4] = byte(n) return e.write(e.buf) } func (e *Encoder) write8(code codes.Code, n uint64) error { e.buf = e.buf[:9] e.buf[0] = byte(code) e.buf[1] = byte(n >> 56) e.buf[2] = byte(n >> 48) e.buf[3] = byte(n >> 40) e.buf[4] = byte(n >> 32) e.buf[5] = byte(n >> 24) e.buf[6] = byte(n >> 16) e.buf[7] = byte(n >> 8) e.buf[8] = byte(n) return e.write(e.buf) } func encodeInt64Value(e *Encoder, v reflect.Value) error { return e.EncodeInt(v.Int()) } func encodeUint64Value(e *Encoder, v reflect.Value) error { return e.EncodeUint(v.Uint()) } func encodeFloat32Value(e *Encoder, v reflect.Value) error { return e.EncodeFloat32(float32(v.Float())) } func encodeFloat64Value(e *Encoder, v reflect.Value) error { return e.EncodeFloat64(v.Float()) } msgpack-3.1.1/encode_slice.go000066400000000000000000000043261313732616500161200ustar00rootroot00000000000000package msgpack import ( "reflect" "github.com/vmihailenco/msgpack/codes" ) func encodeStringValue(e *Encoder, v reflect.Value) error { return e.EncodeString(v.String()) } func encodeByteSliceValue(e *Encoder, v reflect.Value) error { return e.EncodeBytes(v.Bytes()) } func encodeByteArrayValue(e *Encoder, v reflect.Value) error { if err := e.EncodeBytesLen(v.Len()); err != nil { return err } if v.CanAddr() { b := v.Slice(0, v.Len()).Bytes() return e.write(b) } b := make([]byte, v.Len()) reflect.Copy(reflect.ValueOf(b), v) return e.write(b) } func (e *Encoder) EncodeBytesLen(l int) error { if l < 256 { return e.write1(codes.Bin8, uint64(l)) } if l < 65536 { return e.write2(codes.Bin16, uint64(l)) } return e.write4(codes.Bin32, uint32(l)) } func (e *Encoder) encodeStrLen(l int) error { if l < 32 { return e.writeCode(codes.FixedStrLow | codes.Code(l)) } if l < 256 { return e.write1(codes.Str8, uint64(l)) } if l < 65536 { return e.write2(codes.Str16, uint64(l)) } return e.write4(codes.Str32, uint32(l)) } func (e *Encoder) EncodeString(v string) error { if err := e.encodeStrLen(len(v)); err != nil { return err } return e.writeString(v) } func (e *Encoder) EncodeBytes(v []byte) error { if v == nil { return e.EncodeNil() } if err := e.EncodeBytesLen(len(v)); err != nil { return err } return e.write(v) } func (e *Encoder) EncodeArrayLen(l int) error { if l < 16 { return e.writeCode(codes.FixedArrayLow | codes.Code(l)) } if l < 65536 { return e.write2(codes.Array16, uint64(l)) } return e.write4(codes.Array32, uint32(l)) } func (e *Encoder) encodeStringSlice(s []string) error { if s == nil { return e.EncodeNil() } if err := e.EncodeArrayLen(len(s)); err != nil { return err } for _, v := range s { if err := e.EncodeString(v); err != nil { return err } } return nil } func encodeSliceValue(e *Encoder, v reflect.Value) error { if v.IsNil() { return e.EncodeNil() } return encodeArrayValue(e, v) } func encodeArrayValue(e *Encoder, v reflect.Value) error { l := v.Len() if err := e.EncodeArrayLen(l); err != nil { return err } for i := 0; i < l; i++ { if err := e.EncodeValue(v.Index(i)); err != nil { return err } } return nil } msgpack-3.1.1/encode_value.go000066400000000000000000000100601313732616500161250ustar00rootroot00000000000000package msgpack import ( "fmt" "reflect" ) var valueEncoders []encoderFunc func init() { valueEncoders = []encoderFunc{ reflect.Bool: encodeBoolValue, reflect.Int: encodeInt64Value, reflect.Int8: encodeInt64Value, reflect.Int16: encodeInt64Value, reflect.Int32: encodeInt64Value, reflect.Int64: encodeInt64Value, reflect.Uint: encodeUint64Value, reflect.Uint8: encodeUint64Value, reflect.Uint16: encodeUint64Value, reflect.Uint32: encodeUint64Value, reflect.Uint64: encodeUint64Value, reflect.Float32: encodeFloat32Value, reflect.Float64: encodeFloat64Value, reflect.Complex64: encodeUnsupportedValue, reflect.Complex128: encodeUnsupportedValue, reflect.Array: encodeArrayValue, reflect.Chan: encodeUnsupportedValue, reflect.Func: encodeUnsupportedValue, reflect.Interface: encodeInterfaceValue, reflect.Map: encodeMapValue, reflect.Ptr: encodeUnsupportedValue, reflect.Slice: encodeSliceValue, reflect.String: encodeStringValue, reflect.Struct: encodeStructValue, reflect.UnsafePointer: encodeUnsupportedValue, } } func getEncoder(typ reflect.Type) encoderFunc { if encoder, ok := typEncMap[typ]; ok { return encoder } if typ.Implements(customEncoderType) { return encodeCustomValue } if typ.Implements(marshalerType) { return marshalValue } kind := typ.Kind() // Addressable struct field value. if kind != reflect.Ptr { ptr := reflect.PtrTo(typ) if ptr.Implements(customEncoderType) { return encodeCustomValuePtr } if ptr.Implements(marshalerType) { return marshalValuePtr } } if typ == errorType { return encodeErrorValue } switch kind { case reflect.Ptr: return ptrEncoderFunc(typ) case reflect.Slice: if typ.Elem().Kind() == reflect.Uint8 { return encodeByteSliceValue } case reflect.Array: if typ.Elem().Kind() == reflect.Uint8 { return encodeByteArrayValue } case reflect.Map: if typ.Key() == stringType { switch typ.Elem() { case stringType: return encodeMapStringStringValue case interfaceType: return encodeMapStringInterfaceValue } } } return valueEncoders[kind] } func ptrEncoderFunc(typ reflect.Type) encoderFunc { encoder := getEncoder(typ.Elem()) return func(e *Encoder, v reflect.Value) error { if v.IsNil() { return e.EncodeNil() } return encoder(e, v.Elem()) } } func encodeCustomValuePtr(e *Encoder, v reflect.Value) error { if !v.CanAddr() { return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface()) } encoder := v.Addr().Interface().(CustomEncoder) return encoder.EncodeMsgpack(e) } func encodeCustomValue(e *Encoder, v reflect.Value) error { switch v.Kind() { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: if v.IsNil() { return e.EncodeNil() } } encoder := v.Interface().(CustomEncoder) return encoder.EncodeMsgpack(e) } func marshalValuePtr(e *Encoder, v reflect.Value) error { if !v.CanAddr() { return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface()) } return marshalValue(e, v.Addr()) } func marshalValue(e *Encoder, v reflect.Value) error { switch v.Kind() { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: if v.IsNil() { return e.EncodeNil() } } marshaler := v.Interface().(Marshaler) b, err := marshaler.MarshalMsgpack() if err != nil { return err } _, err = e.w.Write(b) return err } func encodeBoolValue(e *Encoder, v reflect.Value) error { return e.EncodeBool(v.Bool()) } func encodeInterfaceValue(e *Encoder, v reflect.Value) error { if v.IsNil() { return e.EncodeNil() } return e.EncodeValue(v.Elem()) } func encodeErrorValue(e *Encoder, v reflect.Value) error { if v.IsNil() { return e.EncodeNil() } return e.EncodeString(v.Interface().(error).Error()) } func encodeUnsupportedValue(e *Encoder, v reflect.Value) error { return fmt.Errorf("msgpack: Encode(unsupported %s)", v.Type()) } msgpack-3.1.1/example_CustomEncoder_test.go000066400000000000000000000013131313732616500210210ustar00rootroot00000000000000package msgpack_test import ( "fmt" "github.com/vmihailenco/msgpack" ) 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 ExampleCustomEncoder() { 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} } msgpack-3.1.1/example_registerExt_test.go000066400000000000000000000024621313732616500205620ustar00rootroot00000000000000package msgpack_test import ( "encoding/binary" "fmt" "time" "github.com/vmihailenco/msgpack" ) func init() { msgpack.RegisterExt(0, (*EventTime)(nil)) } // 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 ExampleRegisterExt() { 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 } msgpack-3.1.1/example_test.go000066400000000000000000000066071313732616500162020ustar00rootroot00000000000000package msgpack_test import ( "bytes" "fmt" "github.com/vmihailenco/msgpack" ) 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 } func ExampleMarshal_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 } func ExampleDecoder_SetDecodeMapFunc() { buf := new(bytes.Buffer) enc := msgpack.NewEncoder(buf) in := map[string]string{"hello": "world"} err := enc.Encode(in) if err != nil { panic(err) } dec := msgpack.NewDecoder(buf) dec.SetDecodeMapFunc(func(d *msgpack.Decoder) (interface{}, error) { n, err := d.DecodeMapLen() if err != nil { return nil, err } m := make(map[string]string, n) for i := 0; i < n; i++ { mk, err := d.DecodeString() if err != nil { return nil, err } mv, err := d.DecodeString() 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[hello:world] } func ExampleDecoder_Query() { 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 ExampleEncoder_StructAsArray() { 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 ExampleMarshal_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] } func ExampleMarshal_omitEmpty() { type Item struct { Foo string Bar string } item := &Item{ Foo: "hello", } b, err := msgpack.Marshal(item) if err != nil { panic(err) } fmt.Printf("item: %q\n", b) type ItemOmitEmpty struct { _msgpack struct{} `msgpack:",omitempty"` Foo string Bar string } itemOmitEmpty := &ItemOmitEmpty{ Foo: "hello", } b, err = msgpack.Marshal(itemOmitEmpty) if err != nil { panic(err) } fmt.Printf("item2: %q\n", b) // Output: item: "\x82\xa3Foo\xa5hello\xa3Bar\xa0" // item2: "\x81\xa3Foo\xa5hello" } msgpack-3.1.1/ext.go000066400000000000000000000076361313732616500143130ustar00rootroot00000000000000package msgpack import ( "bytes" "fmt" "reflect" "sync" "github.com/vmihailenco/msgpack/codes" ) var extTypes = make(map[int8]reflect.Type) var bufferPool = &sync.Pool{ New: func() interface{} { return new(bytes.Buffer) }, } // 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. func RegisterExt(id int8, value interface{}) { typ := reflect.TypeOf(value) if typ.Kind() == reflect.Ptr { typ = typ.Elem() } ptr := reflect.PtrTo(typ) if _, ok := extTypes[id]; ok { panic(fmt.Errorf("msgpack: ext with id=%d is already registered", id)) } extTypes[id] = typ registerExt(id, ptr, getEncoder(ptr), nil) registerExt(id, typ, getEncoder(typ), getDecoder(typ)) } func registerExt(id int8, typ reflect.Type, enc encoderFunc, dec decoderFunc) { if enc != nil { typEncMap[typ] = makeExtEncoder(id, enc) } if dec != nil { typDecMap[typ] = dec } } func makeExtEncoder(typeId int8, enc encoderFunc) encoderFunc { return func(e *Encoder, v reflect.Value) error { buf := bufferPool.Get().(*bytes.Buffer) defer bufferPool.Put(buf) buf.Reset() oldw := e.w e.w = buf err := enc(e, v) e.w = oldw if err != nil { return err } if err := e.encodeExtLen(buf.Len()); err != nil { return err } if err := e.w.WriteByte(byte(typeId)); err != nil { return err } return e.write(buf.Bytes()) } } func (e *Encoder) encodeExtLen(l int) error { switch l { case 1: return e.writeCode(codes.FixExt1) case 2: return e.writeCode(codes.FixExt2) case 4: return e.writeCode(codes.FixExt4) case 8: return e.writeCode(codes.FixExt8) case 16: return e.writeCode(codes.FixExt16) } if l < 256 { return e.write1(codes.Ext8, uint64(l)) } if l < 65536 { return e.write2(codes.Ext16, uint64(l)) } return e.write4(codes.Ext32, uint32(l)) } func (d *Decoder) decodeExtLen() (int, error) { c, err := d.readCode() if err != nil { return 0, err } return d.parseExtLen(c) } func (d *Decoder) parseExtLen(c codes.Code) (int, error) { switch c { case codes.FixExt1: return 1, nil case codes.FixExt2: return 2, nil case codes.FixExt4: return 4, nil case codes.FixExt8: return 8, nil case codes.FixExt16: return 16, nil case codes.Ext8: n, err := d.uint8() return int(n), err case codes.Ext16: n, err := d.uint16() return int(n), err case codes.Ext32: n, err := d.uint32() return int(n), err default: return 0, fmt.Errorf("msgpack: invalid code=%x decoding ext length", c) } } func (d *Decoder) decodeExt() (interface{}, error) { c, err := d.readCode() if err != nil { return 0, err } return d.ext(c) } func (d *Decoder) ext(c codes.Code) (interface{}, error) { extLen, err := d.parseExtLen(c) if err != nil { return nil, err } // Save for later use. d.extLen = extLen extId, err := d.readCode() if err != nil { return nil, err } typ, ok := extTypes[int8(extId)] if !ok { return nil, fmt.Errorf("msgpack: unregistered ext id=%d", extId) } v := reflect.New(typ).Elem() if err := d.DecodeValue(v); err != nil { return nil, err } return v.Interface(), nil } func (d *Decoder) skipExt(c codes.Code) error { n, err := d.parseExtLen(c) if err != nil { return err } return d.skipN(n) } func (d *Decoder) skipExtHeader(c codes.Code) error { // Read ext type. _, err := d.readCode() if err != nil { return err } // Read ext body len. for i := 0; i < extHeaderLen(c); i++ { _, err := d.readCode() if err != nil { return err } } return nil } func extHeaderLen(c codes.Code) int { switch c { case codes.Ext8: return 1 case codes.Ext16: return 2 case codes.Ext32: return 4 } return 0 } msgpack-3.1.1/ext_test.go000066400000000000000000000043021313732616500153350ustar00rootroot00000000000000package msgpack_test import ( "reflect" "testing" "github.com/vmihailenco/msgpack" "github.com/vmihailenco/msgpack/codes" ) func init() { msgpack.RegisterExt(9, (*ExtTest)(nil)) } func TestRegisterExtPanic(t *testing.T) { defer func() { r := recover() if r == nil { t.Fatalf("panic expected") } got := r.(error).Error() wanted := "msgpack: ext with id=9 is already registered" if got != wanted { t.Fatalf("got %q, wanted %q", got, wanted) } }() msgpack.RegisterExt(9, (*ExtTest)(nil)) } type ExtTest struct { S string } var _ msgpack.CustomEncoder = (*ExtTest)(nil) var _ msgpack.CustomDecoder = (*ExtTest)(nil) func (ext ExtTest) EncodeMsgpack(e *msgpack.Encoder) error { return e.EncodeString("hello " + ext.S) } func (ext *ExtTest) DecodeMsgpack(d *msgpack.Decoder) error { var err error ext.S, err = d.DecodeString() return err } func TestExt(t *testing.T) { for _, v := range []interface{}{ExtTest{"world"}, &ExtTest{"world"}} { b, err := msgpack.Marshal(v) if err != nil { t.Fatal(err) } var dst interface{} err = msgpack.Unmarshal(b, &dst) if err != nil { t.Fatal(err) } v, ok := dst.(ExtTest) if !ok { t.Fatalf("got %#v, wanted ExtTest", dst) } wanted := "hello world" if v.S != wanted { t.Fatalf("got %q, wanted %q", v.S, wanted) } var ext ExtTest err = msgpack.Unmarshal(b, &ext) if err != nil { t.Fatal(err) } if ext.S != wanted { t.Fatalf("got %q, wanted %q", ext.S, wanted) } } } func TestUnknownExt(t *testing.T) { b := []byte{byte(codes.FixExt1), 1, 0} var dst interface{} err := msgpack.Unmarshal(b, &dst) if err == nil { t.Fatalf("got nil, wanted error") } got := err.Error() wanted := "msgpack: unregistered ext id=1" if got != wanted { t.Fatalf("got %q, wanted %q", got, wanted) } } func TestDecodeExtWithMap(t *testing.T) { type S struct { I int } msgpack.RegisterExt(2, S{}) b, err := msgpack.Marshal(&S{I: 42}) if err != nil { t.Fatal(err) } var got map[string]interface{} if err := msgpack.Unmarshal(b, &got); err != nil { t.Fatal(err) } wanted := map[string]interface{}{"I": int8(42)} if !reflect.DeepEqual(got, wanted) { t.Fatalf("got %#v, but wanted %#v", got, wanted) } } msgpack-3.1.1/msgpack.go000066400000000000000000000004221313732616500151220ustar00rootroot00000000000000package msgpack type Marshaler interface { MarshalMsgpack() ([]byte, error) } type Unmarshaler interface { UnmarshalMsgpack([]byte) error } type CustomEncoder interface { EncodeMsgpack(*Encoder) error } type CustomDecoder interface { DecodeMsgpack(*Decoder) error } msgpack-3.1.1/msgpack_test.go000066400000000000000000000341211313732616500161640ustar00rootroot00000000000000package msgpack_test import ( "bufio" "bytes" "math" "reflect" "strings" "testing" "time" . "gopkg.in/check.v1" "github.com/vmihailenco/msgpack" "github.com/vmihailenco/msgpack/codes" ) type nameStruct struct { Name string } func TestGocheck(t *testing.T) { TestingT(t) } type MsgpackTest struct { buf *bytes.Buffer enc *msgpack.Encoder dec *msgpack.Decoder } var _ = Suite(&MsgpackTest{}) func (t *MsgpackTest) SetUpTest(c *C) { t.buf = &bytes.Buffer{} t.enc = msgpack.NewEncoder(t.buf) t.dec = msgpack.NewDecoder(bufio.NewReader(t.buf)) } func (t *MsgpackTest) TestUint64(c *C) { table := []struct { v uint64 b []byte }{ {0, []byte{0x00}}, {1, []byte{0x01}}, {math.MaxInt8 - 1, []byte{0x7e}}, {math.MaxInt8, []byte{0x7f}}, {math.MaxInt8 + 1, []byte{0xcc, 0x80}}, {math.MaxUint8 - 1, []byte{0xcc, 0xfe}}, {math.MaxUint8, []byte{0xcc, 0xff}}, {math.MaxUint8 + 1, []byte{0xcd, 0x1, 0x0}}, {math.MaxUint16 - 1, []byte{0xcd, 0xff, 0xfe}}, {math.MaxUint16, []byte{0xcd, 0xff, 0xff}}, {math.MaxUint16 + 1, []byte{0xce, 0x0, 0x1, 0x0, 0x0}}, {math.MaxUint32 - 1, []byte{0xce, 0xff, 0xff, 0xff, 0xfe}}, {math.MaxUint32, []byte{0xce, 0xff, 0xff, 0xff, 0xff}}, {math.MaxUint32 + 1, []byte{0xcf, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0}}, {math.MaxInt64 - 1, []byte{0xcf, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}, {math.MaxInt64, []byte{0xcf, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, } for _, r := range table { var int64v int64 c.Assert(t.enc.Encode(r.v), IsNil) c.Assert(t.buf.Bytes(), DeepEquals, r.b, Commentf("n=%d", r.v)) c.Assert(t.dec.Decode(&int64v), IsNil, Commentf("n=%d", r.v)) c.Assert(int64v, Equals, int64(r.v), Commentf("n=%d", r.v)) var uint64v uint64 c.Assert(t.enc.Encode(r.v), IsNil) c.Assert(t.buf.Bytes(), DeepEquals, r.b, Commentf("n=%d", r.v)) c.Assert(t.dec.Decode(&uint64v), IsNil, Commentf("n=%d", r.v)) c.Assert(uint64v, Equals, uint64(r.v), Commentf("n=%d", r.v)) } } func (t *MsgpackTest) TestInt64(c *C) { table := []struct { v int64 b []byte }{ {math.MinInt64, []byte{0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {math.MinInt32 - 1, []byte{0xd3, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff}}, {math.MinInt32, []byte{0xd2, 0x80, 0x00, 0x00, 0x00}}, {math.MinInt32 + 1, []byte{0xd2, 0x80, 0x00, 0x00, 0x01}}, {math.MinInt16 - 1, []byte{0xd2, 0xff, 0xff, 0x7f, 0xff}}, {math.MinInt16, []byte{0xd1, 0x80, 0x00}}, {math.MinInt16 + 1, []byte{0xd1, 0x80, 0x01}}, {math.MinInt8 - 1, []byte{0xd1, 0xff, 0x7f}}, {math.MinInt8, []byte{0xd0, 0x80}}, {math.MinInt8 + 1, []byte{0xd0, 0x81}}, {-33, []byte{0xd0, 0xdf}}, {-32, []byte{0xe0}}, {-31, []byte{0xe1}}, {-1, []byte{0xff}}, {0, []byte{0x00}}, {1, []byte{0x01}}, {math.MaxInt8 - 1, []byte{0x7e}}, {math.MaxInt8, []byte{0x7f}}, {math.MaxInt8 + 1, []byte{0xcc, 0x80}}, {math.MaxUint8 - 1, []byte{0xcc, 0xfe}}, {math.MaxUint8, []byte{0xcc, 0xff}}, {math.MaxUint8 + 1, []byte{0xcd, 0x1, 0x0}}, {math.MaxUint16 - 1, []byte{0xcd, 0xff, 0xfe}}, {math.MaxUint16, []byte{0xcd, 0xff, 0xff}}, {math.MaxUint16 + 1, []byte{0xce, 0x0, 0x1, 0x0, 0x0}}, {math.MaxUint32 - 1, []byte{0xce, 0xff, 0xff, 0xff, 0xfe}}, {math.MaxUint32, []byte{0xce, 0xff, 0xff, 0xff, 0xff}}, {math.MaxUint32 + 1, []byte{0xcf, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0}}, {math.MaxInt64 - 1, []byte{0xcf, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}, {math.MaxInt64, []byte{0xcf, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, } for _, r := range table { var int64v int64 c.Assert(t.enc.Encode(r.v), IsNil) c.Assert(t.buf.Bytes(), DeepEquals, r.b, Commentf("n=%d", r.v)) c.Assert(t.dec.Decode(&int64v), IsNil, Commentf("n=%d", r.v)) c.Assert(int64v, Equals, int64(r.v), Commentf("n=%d", r.v)) var uint64v uint64 c.Assert(t.enc.Encode(r.v), IsNil) c.Assert(t.buf.Bytes(), DeepEquals, r.b, Commentf("n=%d", r.v)) c.Assert(t.dec.Decode(&uint64v), IsNil, Commentf("n=%d", r.v)) c.Assert(uint64v, Equals, uint64(r.v), Commentf("n=%d", r.v)) } } func (t *MsgpackTest) TestFloat32(c *C) { table := []struct { v float32 b []byte }{ {0.1, []byte{byte(codes.Float), 0x3d, 0xcc, 0xcc, 0xcd}}, {0.2, []byte{byte(codes.Float), 0x3e, 0x4c, 0xcc, 0xcd}}, {-0.1, []byte{byte(codes.Float), 0xbd, 0xcc, 0xcc, 0xcd}}, {-0.2, []byte{byte(codes.Float), 0xbe, 0x4c, 0xcc, 0xcd}}, {float32(math.Inf(1)), []byte{byte(codes.Float), 0x7f, 0x80, 0x00, 0x00}}, {float32(math.Inf(-1)), []byte{byte(codes.Float), 0xff, 0x80, 0x00, 0x00}}, {math.MaxFloat32, []byte{byte(codes.Float), 0x7f, 0x7f, 0xff, 0xff}}, {math.SmallestNonzeroFloat32, []byte{byte(codes.Float), 0x0, 0x0, 0x0, 0x1}}, } for _, r := range table { c.Assert(t.enc.Encode(r.v), IsNil) c.Assert(t.buf.Bytes(), DeepEquals, r.b, Commentf("err encoding %v", r.v)) var f32 float32 c.Assert(t.dec.Decode(&f32), IsNil) c.Assert(f32, Equals, r.v) // Pass pointer to skip fast-path and trigger reflect. c.Assert(t.enc.Encode(&r.v), IsNil) c.Assert(t.buf.Bytes(), DeepEquals, r.b, Commentf("err encoding %v", r.v)) var f64 float64 c.Assert(t.dec.Decode(&f64), IsNil) c.Assert(float32(f64), Equals, r.v) c.Assert(t.enc.Encode(r.v), IsNil) iface, err := t.dec.DecodeInterface() c.Assert(err, IsNil) c.Assert(iface, Equals, r.v) } in := float32(math.NaN()) c.Assert(t.enc.Encode(in), IsNil) var out float32 c.Assert(t.dec.Decode(&out), IsNil) c.Assert(math.IsNaN(float64(out)), Equals, true) } func (t *MsgpackTest) TestFloat64(c *C) { table := []struct { v float64 b []byte }{ {.1, []byte{0xcb, 0x3f, 0xb9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a}}, {.2, []byte{0xcb, 0x3f, 0xc9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a}}, {-.1, []byte{0xcb, 0xbf, 0xb9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a}}, {-.2, []byte{0xcb, 0xbf, 0xc9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a}}, {math.Inf(1), []byte{0xcb, 0x7f, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, {math.Inf(-1), []byte{0xcb, 0xff, 0xf0, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0}}, {math.MaxFloat64, []byte{0xcb, 0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, {math.SmallestNonzeroFloat64, []byte{0xcb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}}, } for _, r := range table { c.Assert(t.enc.Encode(r.v), IsNil) c.Assert(t.buf.Bytes(), DeepEquals, r.b, Commentf("err encoding %v", r.v)) var v float64 c.Assert(t.dec.Decode(&v), IsNil) c.Assert(v, Equals, r.v) c.Assert(t.enc.Encode(r.v), IsNil) iface, err := t.dec.DecodeInterface() c.Assert(err, IsNil) c.Assert(iface, Equals, r.v) } in := math.NaN() c.Assert(t.enc.Encode(in), IsNil) var out float64 c.Assert(t.dec.Decode(&out), IsNil) c.Assert(math.IsNaN(out), Equals, true) } func (t *MsgpackTest) TestDecodeNil(c *C) { c.Assert(t.dec.Decode(nil), NotNil) } func (t *MsgpackTest) TestTime(c *C) { in := time.Now() var out time.Time c.Assert(t.enc.Encode(in), IsNil) c.Assert(t.dec.Decode(&out), IsNil) c.Assert(out.Equal(in), Equals, true) var zero time.Time c.Assert(t.enc.Encode(zero), IsNil) c.Assert(t.dec.Decode(&out), IsNil) c.Assert(out.Equal(zero), Equals, true) c.Assert(out.IsZero(), Equals, true) } func (t *MsgpackTest) TestBin(c *C) { lowBin8 := []byte(strings.Repeat("w", 32)) highBin8 := []byte(strings.Repeat("w", 255)) lowBin16 := []byte(strings.Repeat("w", 256)) highBin16 := []byte(strings.Repeat("w", 65535)) lowBin32 := []byte(strings.Repeat("w", 65536)) for _, i := range []struct { src []byte b []byte }{ { lowBin8, append([]byte{0xc4, byte(len(lowBin8))}, lowBin8...), }, { highBin8, append([]byte{0xc4, byte(len(highBin8))}, highBin8...), }, { lowBin16, append([]byte{0xc5, 1, 0}, lowBin16...), }, { highBin16, append([]byte{0xc5, 255, 255}, highBin16...), }, { lowBin32, append([]byte{0xc6, 0, 1, 0, 0}, lowBin32...), }, } { c.Assert(t.enc.Encode(i.src), IsNil) c.Assert(t.buf.Bytes(), DeepEquals, i.b) var dst []byte c.Assert(t.dec.Decode(&dst), IsNil) c.Assert(dst, DeepEquals, i.src) c.Assert(t.enc.Encode(i.src), IsNil) iface, err := t.dec.DecodeInterface() c.Assert(err, IsNil) c.Assert(iface, DeepEquals, i.src) } } func (t *MsgpackTest) TestString(c *C) { highFixStr := strings.Repeat("w", 31) lowStr8 := strings.Repeat("w", 32) highStr8 := strings.Repeat("w", 255) lowStr16 := strings.Repeat("w", 256) highStr16 := strings.Repeat("w", 65535) lowStr32 := strings.Repeat("w", 65536) for _, i := range []struct { src string b []byte }{ {"", []byte{0xa0}}, // fixstr {"a", []byte{0xa1, 'a'}}, // fixstr {"hello", append([]byte{0xa5}, "hello"...)}, // fixstr { highFixStr, append([]byte{0xbf}, highFixStr...), }, { lowStr8, append([]byte{0xd9, byte(len(lowStr8))}, lowStr8...), }, { highStr8, append([]byte{0xd9, byte(len(highStr8))}, highStr8...), }, { lowStr16, append([]byte{0xda, 1, 0}, lowStr16...), }, { highStr16, append([]byte{0xda, 255, 255}, highStr16...), }, { lowStr32, append([]byte{0xdb, 0, 1, 0, 0}, lowStr32...), }, } { c.Assert(t.enc.Encode(i.src), IsNil) c.Assert(t.buf.Bytes(), DeepEquals, i.b) var dst string c.Assert(t.dec.Decode(&dst), IsNil) c.Assert(dst, Equals, i.src) c.Assert(t.enc.Encode(i.src), IsNil) iface, err := t.dec.DecodeInterface() c.Assert(err, IsNil) c.Assert(iface, DeepEquals, i.src) } } func (t *MsgpackTest) TestLargeBytes(c *C) { N := int(1e6) src := bytes.Repeat([]byte{'1'}, N) c.Assert(t.enc.Encode(src), IsNil) var dst []byte c.Assert(t.dec.Decode(&dst), IsNil) c.Assert(dst, DeepEquals, src) } func (t *MsgpackTest) TestLargeString(c *C) { N := int(1e6) src := string(bytes.Repeat([]byte{'1'}, N)) c.Assert(t.enc.Encode(src), IsNil) var dst string c.Assert(t.dec.Decode(&dst), IsNil) c.Assert(dst, Equals, src) } func (t *MsgpackTest) TestSliceOfStructs(c *C) { in := []*nameStruct{&nameStruct{"hello"}} var out []*nameStruct c.Assert(t.enc.Encode(in), IsNil) c.Assert(t.dec.Decode(&out), IsNil) c.Assert(out, DeepEquals, in) } func (t *MsgpackTest) TestMap(c *C) { for _, i := range []struct { m map[string]string b []byte }{ {map[string]string{}, []byte{0x80}}, {map[string]string{"hello": "world"}, []byte{0x81, 0xa5, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xa5, 0x77, 0x6f, 0x72, 0x6c, 0x64}}, } { c.Assert(t.enc.Encode(i.m), IsNil) c.Assert(t.buf.Bytes(), DeepEquals, i.b, Commentf("err encoding %v", i.m)) var m map[string]string c.Assert(t.dec.Decode(&m), IsNil) c.Assert(m, DeepEquals, i.m) } } func (t *MsgpackTest) TestStructNil(c *C) { var dst *nameStruct c.Assert(t.enc.Encode(nameStruct{Name: "foo"}), IsNil) c.Assert(t.dec.Decode(&dst), IsNil) c.Assert(dst, Not(IsNil)) c.Assert(dst.Name, Equals, "foo") } func (t *MsgpackTest) TestStructUnknownField(c *C) { in := struct { Field1 string Field2 string Field3 string }{ Field1: "value1", Field2: "value2", Field3: "value3", } c.Assert(t.enc.Encode(in), IsNil) out := struct { Field2 string }{} c.Assert(t.dec.Decode(&out), IsNil) c.Assert(out.Field2, Equals, "value2") } //------------------------------------------------------------------------------ type coderStruct struct { name string } type wrapperStruct struct { coderStruct } var ( _ msgpack.CustomEncoder = (*coderStruct)(nil) _ msgpack.CustomDecoder = (*coderStruct)(nil) ) func (s *coderStruct) Name() string { return s.name } func (s *coderStruct) EncodeMsgpack(enc *msgpack.Encoder) error { return enc.Encode(s.name) } func (s *coderStruct) DecodeMsgpack(dec *msgpack.Decoder) error { return dec.Decode(&s.name) } func (t *MsgpackTest) TestCoder(c *C) { in := &coderStruct{name: "hello"} var out coderStruct c.Assert(t.enc.Encode(in), IsNil) c.Assert(t.dec.Decode(&out), IsNil) c.Assert(out.Name(), Equals, "hello") } func (t *MsgpackTest) TestNilCoder(c *C) { in := &coderStruct{name: "hello"} var out *coderStruct c.Assert(t.enc.Encode(in), IsNil) c.Assert(t.dec.Decode(&out), IsNil) c.Assert(out.Name(), Equals, "hello") } func (t *MsgpackTest) TestNilCoderValue(c *C) { in := &coderStruct{name: "hello"} var out *coderStruct c.Assert(t.enc.Encode(in), IsNil) c.Assert(t.dec.DecodeValue(reflect.ValueOf(&out)), IsNil) c.Assert(out.Name(), Equals, "hello") } func (t *MsgpackTest) TestPtrToCoder(c *C) { in := &coderStruct{name: "hello"} var out coderStruct out2 := &out c.Assert(t.enc.Encode(in), IsNil) c.Assert(t.dec.Decode(&out2), IsNil) c.Assert(out.Name(), Equals, "hello") } func (t *MsgpackTest) TestWrappedCoder(c *C) { in := &wrapperStruct{coderStruct: coderStruct{name: "hello"}} var out wrapperStruct c.Assert(t.enc.Encode(in), IsNil) c.Assert(t.dec.Decode(&out), IsNil) c.Assert(out.Name(), Equals, "hello") } //------------------------------------------------------------------------------ type struct2 struct { Name string } type struct1 struct { Name string Struct2 struct2 } func (t *MsgpackTest) TestNestedStructs(c *C) { in := &struct1{Name: "hello", Struct2: struct2{Name: "world"}} var out struct1 c.Assert(t.enc.Encode(in), IsNil) c.Assert(t.dec.Decode(&out), IsNil) c.Assert(out.Name, Equals, in.Name) c.Assert(out.Struct2.Name, Equals, in.Struct2.Name) } type Struct4 struct { Name2 string } type Struct3 struct { Struct4 Name1 string } func TestEmbedding(t *testing.T) { in := &Struct3{ Name1: "hello", Struct4: Struct4{ Name2: "world", }, } var out Struct3 b, err := msgpack.Marshal(in) if err != nil { t.Fatal(err) } err = msgpack.Unmarshal(b, &out) if err != nil { t.Fatal(err) } if out.Name1 != in.Name1 { t.Fatalf("") } if out.Name2 != in.Name2 { t.Fatalf("") } } func (t *MsgpackTest) TestSliceNil(c *C) { in := [][]*int{nil} var out [][]*int c.Assert(t.enc.Encode(in), IsNil) c.Assert(t.dec.Decode(&out), IsNil) c.Assert(out, DeepEquals, in) } //------------------------------------------------------------------------------ func (t *MsgpackTest) TestMapStringInterface(c *C) { in := map[string]interface{}{ "foo": "bar", "hello": map[string]interface{}{ "foo": "bar", }, } var out map[string]interface{} c.Assert(t.enc.Encode(in), IsNil) c.Assert(t.dec.Decode(&out), IsNil) c.Assert(out["foo"], Equals, "bar") mm := out["hello"].(map[string]interface{}) c.Assert(mm["foo"], Equals, "bar") } msgpack-3.1.1/tag.go000066400000000000000000000013521313732616500142530ustar00rootroot00000000000000package msgpack import ( "strings" ) type tagOptions string func (o tagOptions) Get(name string) (string, bool) { s := string(o) for len(s) > 0 { var next string idx := strings.IndexByte(s, ',') if idx >= 0 { s, next = s[:idx], s[idx+1:] } if strings.HasPrefix(s, name) { return s[len(name):], true } s = next } return "", false } func (o tagOptions) Contains(name string) bool { _, ok := o.Get(name) return ok } func parseTag(tag string) (string, tagOptions) { if idx := strings.IndexByte(tag, ','); idx != -1 { name := tag[:idx] if strings.IndexByte(name, ':') == -1 { return name, tagOptions(tag[idx+1:]) } } if strings.IndexByte(tag, ':') == -1 { return tag, "" } return "", tagOptions(tag) } msgpack-3.1.1/time.go000066400000000000000000000045211313732616500144370ustar00rootroot00000000000000package msgpack import ( "encoding/binary" "fmt" "reflect" "time" "github.com/vmihailenco/msgpack/codes" ) var timeExtId int8 = -1 func init() { timeType := reflect.TypeOf((*time.Time)(nil)).Elem() registerExt(timeExtId, timeType, encodeTimeValue, decodeTimeValue) } func (e *Encoder) EncodeTime(tm time.Time) error { b := e.encodeTime(tm) if err := e.encodeExtLen(len(b)); err != nil { return err } if err := e.w.WriteByte(byte(timeExtId)); err != nil { return err } return e.write(b) } func (e *Encoder) encodeTime(tm time.Time) []byte { secs := uint64(tm.Unix()) if secs>>34 == 0 { data := uint64(tm.Nanosecond())<<34 | secs if data&0xffffffff00000000 == 0 { b := make([]byte, 4) binary.BigEndian.PutUint32(b, uint32(data)) return b } else { b := make([]byte, 8) binary.BigEndian.PutUint64(b, data) return b } } b := make([]byte, 12) binary.BigEndian.PutUint32(b, uint32(tm.Nanosecond())) binary.BigEndian.PutUint64(b[4:], uint64(secs)) return b } func (d *Decoder) DecodeTime() (time.Time, error) { c, err := d.readCode() if err != nil { return time.Time{}, err } // Legacy format. if c == codes.FixedArrayLow|2 { sec, err := d.DecodeInt64() if err != nil { return time.Time{}, err } nsec, err := d.DecodeInt64() if err != nil { return time.Time{}, err } return time.Unix(sec, nsec), nil } extLen, err := d.parseExtLen(c) if err != nil { return time.Time{}, err } _, err = d.r.ReadByte() if err != nil { return time.Time{}, nil } b, err := d.readN(extLen) if err != nil { return time.Time{}, err } switch len(b) { case 4: sec := binary.BigEndian.Uint32(b) return time.Unix(int64(sec), 0), nil case 8: sec := binary.BigEndian.Uint64(b) nsec := int64(sec >> 34) sec &= 0x00000003ffffffff return time.Unix(int64(sec), nsec), nil case 12: nsec := binary.BigEndian.Uint32(b) sec := binary.BigEndian.Uint64(b[4:]) return time.Unix(int64(sec), int64(nsec)), nil default: return time.Time{}, fmt.Errorf("msgpack: invalid ext len=%d decoding time", extLen) } } func encodeTimeValue(e *Encoder, v reflect.Value) error { tm := v.Interface().(time.Time) b := e.encodeTime(tm) return e.write(b) } func decodeTimeValue(d *Decoder, v reflect.Value) error { tm, err := d.DecodeTime() if err != nil { return err } v.Set(reflect.ValueOf(tm)) return nil } msgpack-3.1.1/types.go000066400000000000000000000122471313732616500146510ustar00rootroot00000000000000package msgpack import ( "reflect" "sync" ) var errorType = reflect.TypeOf((*error)(nil)).Elem() var customEncoderType = reflect.TypeOf((*CustomEncoder)(nil)).Elem() var customDecoderType = reflect.TypeOf((*CustomDecoder)(nil)).Elem() var marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() var unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() type encoderFunc func(*Encoder, reflect.Value) error type decoderFunc func(*Decoder, reflect.Value) error var typEncMap = make(map[reflect.Type]encoderFunc) var typDecMap = make(map[reflect.Type]decoderFunc) // Register registers encoder and decoder functions for a value. // This is low level API and in most cases you should prefer implementing // Marshaler/CustomEncoder and Unmarshaler/CustomDecoder interfaces. func Register(value interface{}, enc encoderFunc, dec decoderFunc) { typ := reflect.TypeOf(value) if enc != nil { typEncMap[typ] = enc } if dec != nil { typDecMap[typ] = dec } } //------------------------------------------------------------------------------ var structs = newStructCache() type structCache struct { mu sync.RWMutex m map[reflect.Type]*fields } func newStructCache() *structCache { return &structCache{ m: make(map[reflect.Type]*fields), } } func (m *structCache) Fields(typ reflect.Type) *fields { m.mu.RLock() fs, ok := m.m[typ] m.mu.RUnlock() if ok { return fs } m.mu.Lock() fs, ok = m.m[typ] if !ok { fs = getFields(typ) m.m[typ] = fs } m.mu.Unlock() return fs } //------------------------------------------------------------------------------ type field struct { name string index []int omitEmpty bool encoder encoderFunc decoder decoderFunc } func (f *field) value(strct reflect.Value) reflect.Value { return strct.FieldByIndex(f.index) } func (f *field) Omit(strct reflect.Value) bool { return f.omitEmpty && isEmptyValue(f.value(strct)) } func (f *field) EncodeValue(e *Encoder, strct reflect.Value) error { return f.encoder(e, f.value(strct)) } func (f *field) DecodeValue(d *Decoder, strct reflect.Value) error { return f.decoder(d, f.value(strct)) } //------------------------------------------------------------------------------ type fields struct { List []*field Table map[string]*field asArray bool omitEmpty bool } func newFields(numField int) *fields { return &fields{ List: make([]*field, 0, numField), Table: make(map[string]*field, numField), } } func (fs *fields) Len() int { return len(fs.List) } func (fs *fields) Add(field *field) { fs.List = append(fs.List, field) fs.Table[field.name] = field if field.omitEmpty { fs.omitEmpty = field.omitEmpty } } func (fs *fields) OmitEmpty(strct reflect.Value) []*field { if !fs.omitEmpty { return fs.List } fields := make([]*field, 0, fs.Len()) for _, f := range fs.List { if !f.Omit(strct) { fields = append(fields, f) } } return fields } func getFields(typ reflect.Type) *fields { numField := typ.NumField() fs := newFields(numField) var omitEmpty bool for i := 0; i < numField; i++ { f := typ.Field(i) name, opt := parseTag(f.Tag.Get("msgpack")) if name == "-" { continue } if f.Name == "_msgpack" { if opt.Contains("asArray") { fs.asArray = true } if opt.Contains("omitempty") { omitEmpty = true } } if f.PkgPath != "" && !f.Anonymous { continue } if name == "" { name = f.Name } field := &field{ name: name, index: f.Index, omitEmpty: omitEmpty || opt.Contains("omitempty"), encoder: getEncoder(f.Type), decoder: getDecoder(f.Type), } if f.Anonymous && inlineFields(fs, f.Type, field) { continue } fs.Add(field) } return fs } var encodeStructValuePtr uintptr var decodeStructValuePtr uintptr func init() { encodeStructValuePtr = reflect.ValueOf(encodeStructValue).Pointer() decodeStructValuePtr = reflect.ValueOf(decodeStructValue).Pointer() } func inlineFields(fs *fields, typ reflect.Type, f *field) bool { var encoder encoderFunc var decoder decoderFunc if typ.Kind() == reflect.Struct { encoder = f.encoder decoder = f.decoder } else { for typ.Kind() == reflect.Ptr { typ = typ.Elem() encoder = getEncoder(typ) decoder = getDecoder(typ) } if typ.Kind() != reflect.Struct { return false } } if reflect.ValueOf(encoder).Pointer() != encodeStructValuePtr { return false } if reflect.ValueOf(decoder).Pointer() != decodeStructValuePtr { return false } inlinedFields := getFields(typ).List for _, field := range inlinedFields { if _, ok := fs.Table[field.name]; ok { // Don't overwrite shadowed fields. continue } field.index = append(f.index, field.index...) fs.Add(field) } return true } func isEmptyValue(v reflect.Value) bool { switch v.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: return v.Len() == 0 case reflect.Bool: return !v.Bool() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return v.Uint() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Interface, reflect.Ptr: return v.IsNil() } return false } msgpack-3.1.1/types_test.go000066400000000000000000000307441313732616500157120ustar00rootroot00000000000000package msgpack_test import ( "bytes" "encoding/hex" "fmt" "math" "net/url" "reflect" "strings" "testing" "time" "github.com/vmihailenco/msgpack" "github.com/vmihailenco/msgpack/codes" ) //------------------------------------------------------------------------------ type Object struct { n int } func (o *Object) MarshalMsgpack() ([]byte, error) { return msgpack.Marshal(o.n) } func (o *Object) UnmarshalMsgpack(b []byte) error { return msgpack.Unmarshal(b, &o.n) } //------------------------------------------------------------------------------ type IntSet map[int]struct{} var _ msgpack.CustomEncoder = (*IntSet)(nil) var _ msgpack.CustomDecoder = (*IntSet)(nil) func (set IntSet) EncodeMsgpack(enc *msgpack.Encoder) error { slice := make([]int, 0, len(set)) for n, _ := range set { slice = append(slice, n) } return enc.Encode(slice) } func (setptr *IntSet) DecodeMsgpack(dec *msgpack.Decoder) error { n, err := dec.DecodeArrayLen() if err != nil { return err } set := make(IntSet, n) for i := 0; i < n; i++ { n, err := dec.DecodeInt() if err != nil { return err } set[n] = struct{}{} } *setptr = set return nil } //------------------------------------------------------------------------------ type CustomEncoder struct { str string ref *CustomEncoder num int } var _ msgpack.CustomEncoder = (*CustomEncoder)(nil) var _ msgpack.CustomDecoder = (*CustomEncoder)(nil) func (s *CustomEncoder) EncodeMsgpack(enc *msgpack.Encoder) error { if s == nil { return enc.EncodeNil() } return enc.Encode(s.str, s.ref, s.num) } func (s *CustomEncoder) DecodeMsgpack(dec *msgpack.Decoder) error { return dec.Decode(&s.str, &s.ref, &s.num) } type CustomEncoderField struct { Field CustomEncoder } //------------------------------------------------------------------------------ type OmitEmptyTest struct { Foo string `msgpack:",omitempty"` Bar string `msgpack:",omitempty"` } type InlineTest struct { OmitEmptyTest } type InlinePtrTest struct { *OmitEmptyTest } type AsArrayTest struct { _msgpack struct{} `msgpack:",asArray"` OmitEmptyTest } //------------------------------------------------------------------------------ type encoderTest struct { in interface{} wanted string } var encoderTests = []encoderTest{ {nil, "c0"}, {[]byte(nil), "c0"}, {[]byte{1, 2, 3}, "c403010203"}, {[3]byte{1, 2, 3}, "c403010203"}, {time.Unix(0, 0), "d6ff00000000"}, {time.Unix(1, 1), "d7ff0000000400000001"}, {time.Time{}, "c70cff00000000fffffff1886e0900"}, {IntSet{}, "90"}, {IntSet{8: struct{}{}}, "9108"}, {map[string]string(nil), "c0"}, { map[string]string{"a": "", "b": "", "c": "", "d": "", "e": ""}, "85a161a0a162a0a163a0a164a0a165a0", }, {(*Object)(nil), "c0"}, {&Object{}, "00"}, {&Object{42}, "2a"}, {[]*Object{nil, nil}, "92c0c0"}, {&CustomEncoder{}, "a0c000"}, { &CustomEncoder{"a", &CustomEncoder{"b", nil, 7}, 6}, "a161a162c00706", }, {OmitEmptyTest{}, "80"}, {&OmitEmptyTest{Foo: "hello"}, "81a3466f6fa568656c6c6f"}, {&InlineTest{OmitEmptyTest: OmitEmptyTest{Bar: "world"}}, "81a3426172a5776f726c64"}, {&InlinePtrTest{OmitEmptyTest: &OmitEmptyTest{Bar: "world"}}, "81a3426172a5776f726c64"}, {&AsArrayTest{}, "92a0a0"}, } func TestEncoder(t *testing.T) { for _, test := range encoderTests { var buf bytes.Buffer enc := msgpack.NewEncoder(&buf).SortMapKeys(true) if err := enc.Encode(test.in); err != nil { t.Fatal(err) } s := hex.EncodeToString(buf.Bytes()) if s != test.wanted { t.Fatalf("%s != %s (in=%#v)", s, test.wanted, test.in) } } } //------------------------------------------------------------------------------ type decoderTest struct { b []byte out interface{} err string } var decoderTests = []decoderTest{ {b: []byte{byte(codes.Bin32), 0x0f, 0xff, 0xff, 0xff}, out: new([]byte), err: "EOF"}, {b: []byte{byte(codes.Str32), 0x0f, 0xff, 0xff, 0xff}, out: new([]byte), err: "EOF"}, {b: []byte{byte(codes.Array32), 0x0f, 0xff, 0xff, 0xff}, out: new([]int), err: "EOF"}, {b: []byte{byte(codes.Map32), 0x0f, 0xff, 0xff, 0xff}, out: new(map[int]int), err: "EOF"}, } func TestDecoder(t *testing.T) { for i, test := range decoderTests { err := msgpack.Unmarshal(test.b, test.out) if err == nil { t.Fatalf("#%d err is nil, wanted %q", i, test.err) } if err.Error() != test.err { t.Fatalf("#%d err is %q, wanted %q", i, err.Error(), test.err) } } } //------------------------------------------------------------------------------ type unexported struct { Foo string } type Exported struct { Bar string } type EmbedingTest struct { unexported Exported } //------------------------------------------------------------------------------ type EmbeddedTime struct { time.Time } type ( interfaceAlias interface{} byteAlias byte uint8Alias uint8 stringAlias string sliceByte []byte sliceString []string mapStringString map[string]string mapStringInterface map[string]interface{} ) type StructTest struct { F1 sliceString F2 []string } type typeTest struct { *testing.T in interface{} out interface{} encErr string decErr string wantnil bool wantzero bool wanted interface{} } func (t typeTest) String() string { return fmt.Sprintf("in=%#v, out=%#v", t.in, t.out) } func (t *typeTest) assertErr(err error, s string) { if err == nil { t.Fatalf("got %v error, wanted %q", err, s) } if err.Error() != s { t.Fatalf("got %q error, wanted %q", err, s) } } var ( intSlice = make([]int, 0, 3) repoURL, _ = url.Parse("https://github.com/vmihailenco/msgpack") typeTests = []typeTest{ {in: make(chan bool), encErr: "msgpack: Encode(unsupported chan bool)"}, {in: nil, out: nil, decErr: "msgpack: Decode(nil)"}, {in: nil, out: 0, decErr: "msgpack: Decode(nonsettable int)"}, {in: nil, out: (*int)(nil), decErr: "msgpack: Decode(nonsettable *int)"}, {in: nil, out: new(chan bool), decErr: "msgpack: Decode(unsupported chan bool)"}, {in: true, out: new(bool)}, {in: false, out: new(bool)}, {in: nil, out: new(int), wanted: int(0)}, {in: nil, out: new(*int), wantnil: true}, {in: float32(3.14), out: new(float32)}, {in: int8(-1), out: new(float32), wanted: float32(-1)}, {in: int32(1), out: new(float32), wanted: float32(1)}, {in: int32(999999999), out: new(float32), wanted: float32(999999999)}, {in: int64(math.MaxInt64), out: new(float32), wanted: float32(math.MaxInt64)}, {in: float64(3.14), out: new(float64)}, {in: int8(-1), out: new(float64), wanted: float64(-1)}, {in: int64(1), out: new(float64), wanted: float64(1)}, {in: int64(999999999), out: new(float64), wanted: float64(999999999)}, {in: int64(math.MaxInt64), out: new(float64), wanted: float64(math.MaxInt64)}, {in: nil, out: new(*string), wantnil: true}, {in: nil, out: new(string), wanted: ""}, {in: "", out: new(string)}, {in: "foo", out: new(string)}, {in: nil, out: new([]byte), wantnil: true}, {in: []byte(nil), out: new([]byte), wantnil: true}, {in: []byte(nil), out: &[]byte{}, wantnil: true}, {in: []byte{1, 2, 3}, out: new([]byte)}, {in: []byte{1, 2, 3}, out: new([]byte)}, {in: sliceByte{1, 2, 3}, out: new(sliceByte)}, {in: []byteAlias{1, 2, 3}, out: new([]byteAlias)}, {in: []uint8Alias{1, 2, 3}, out: new([]uint8Alias)}, {in: nil, out: new([3]byte), wanted: [3]byte{}}, {in: [3]byte{1, 2, 3}, out: new([3]byte)}, {in: [3]byte{1, 2, 3}, out: new([2]byte), decErr: "[2]uint8 len is 2, but msgpack has 3 elements"}, {in: nil, out: new([]interface{}), wantnil: true}, {in: nil, out: new([]interface{}), wantnil: true}, {in: []interface{}{int8(1), "hello"}, out: new([]interface{})}, {in: nil, out: new([]int), wantnil: true}, {in: nil, out: &[]int{1, 2}, wantnil: true}, {in: []int(nil), out: new([]int), wantnil: true}, {in: make([]int, 0), out: new([]int)}, {in: []int{}, out: new([]int)}, {in: []int{1, 2, 3}, out: new([]int)}, {in: []int{1, 2, 3}, out: &intSlice}, {in: [3]int{1, 2, 3}, out: new([3]int)}, {in: [3]int{1, 2, 3}, out: new([2]int), decErr: "[2]int len is 2, but msgpack has 3 elements"}, {in: []string(nil), out: new([]string), wantnil: true}, {in: []string{}, out: new([]string)}, {in: []string{"a", "b"}, out: new([]string)}, {in: [2]string{"a", "b"}, out: new([2]string)}, {in: sliceString{"foo", "bar"}, out: new(sliceString)}, {in: []stringAlias{"hello"}, out: new([]stringAlias)}, {in: nil, out: new(map[string]string), wantnil: true}, {in: nil, out: new(map[int]int), wantnil: true}, {in: nil, out: &map[string]string{"foo": "bar"}, wantnil: true}, {in: nil, out: &map[int]int{1: 2}, wantnil: true}, {in: map[string]interface{}{"foo": nil}, out: new(map[string]interface{})}, {in: mapStringString{"foo": "bar"}, out: new(mapStringString)}, {in: map[stringAlias]stringAlias{"foo": "bar"}, out: new(map[stringAlias]stringAlias)}, {in: mapStringInterface{"foo": "bar"}, out: new(mapStringInterface)}, {in: map[stringAlias]interfaceAlias{"foo": "bar"}, out: new(map[stringAlias]interfaceAlias)}, {in: (*Object)(nil), out: new(*Object)}, {in: &Object{42}, out: new(Object)}, {in: []*Object{new(Object), new(Object)}, out: new([]*Object)}, {in: IntSet{}, out: new(IntSet)}, {in: IntSet{42: struct{}{}}, out: new(IntSet)}, {in: IntSet{42: struct{}{}}, out: new(*IntSet)}, {in: StructTest{sliceString{"foo", "bar"}, []string{"hello"}}, out: new(StructTest)}, {in: StructTest{sliceString{"foo", "bar"}, []string{"hello"}}, out: new(*StructTest)}, {in: EmbedingTest{}, out: new(EmbedingTest)}, {in: EmbedingTest{}, out: new(*EmbedingTest)}, { in: EmbedingTest{ unexported: unexported{Foo: "hello"}, Exported: Exported{Bar: "world"}, }, out: new(EmbedingTest), }, {in: time.Unix(0, 0), out: new(time.Time)}, {in: time.Unix(0, 1), out: new(time.Time)}, {in: time.Unix(1, 0), out: new(time.Time)}, {in: time.Unix(1, 1), out: new(time.Time)}, {in: EmbeddedTime{Time: time.Unix(1, 1)}, out: new(EmbeddedTime)}, {in: EmbeddedTime{Time: time.Unix(1, 1)}, out: new(*EmbeddedTime)}, {in: nil, out: new(*CustomEncoder), wantnil: true}, {in: nil, out: &CustomEncoder{str: "a"}, wantzero: true}, { in: &CustomEncoder{"a", &CustomEncoder{"b", nil, 1}, 2}, out: new(CustomEncoder), }, { in: &CustomEncoderField{Field: CustomEncoder{"a", nil, 1}}, out: new(CustomEncoderField), }, {in: repoURL, out: new(url.URL)}, {in: repoURL, out: new(*url.URL)}, {in: nil, out: new(*AsArrayTest), wantnil: true}, {in: nil, out: new(AsArrayTest), wantzero: true}, {in: AsArrayTest{OmitEmptyTest: OmitEmptyTest{"foo", "bar"}}, out: new(AsArrayTest)}, { in: AsArrayTest{OmitEmptyTest: OmitEmptyTest{"foo", "bar"}}, out: new(unexported), wanted: unexported{Foo: "foo"}, }, {in: (*EventTime)(nil), out: new(*EventTime)}, {in: &EventTime{time.Unix(0, 0)}, out: new(EventTime)}, {in: (*ExtTest)(nil), out: new(*ExtTest)}, {in: &ExtTest{"world"}, out: new(ExtTest), wanted: ExtTest{"hello world"}}, } ) func indirect(viface interface{}) interface{} { v := reflect.ValueOf(viface) for v.Kind() == reflect.Ptr { v = v.Elem() } if v.IsValid() { return v.Interface() } return nil } func TestTypes(t *testing.T) { for _, test := range typeTests { test.T = t var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) err := enc.Encode(test.in) if test.encErr != "" { test.assertErr(err, test.encErr) continue } if err != nil { t.Fatalf("Marshal failed: %s (in=%#v)", err, test.in) } dec := msgpack.NewDecoder(&buf) err = dec.Decode(test.out) if test.decErr != "" { test.assertErr(err, test.decErr) continue } if err != nil { t.Fatalf("Unmarshal failed: %s (%s)", err, test) } if buf.Len() > 0 { t.Fatalf("unread data in the buffer: %q (%s)", buf.Bytes(), test) } if test.wantnil { v := reflect.Indirect(reflect.ValueOf(test.out)) if !v.IsNil() { t.Fatalf("got %#v, wanted nil (%s)", test.out, test) } continue } out := indirect(test.out) var wanted interface{} if test.wantzero { typ := reflect.TypeOf(out) wanted = reflect.Zero(typ).Interface() } else { wanted = test.wanted } if wanted == nil { wanted = indirect(test.in) } if !reflect.DeepEqual(out, wanted) { t.Fatalf("%#v != %#v (%s)", out, wanted, test) } } } func TestStrings(t *testing.T) { for _, n := range []int{0, 1, 31, 32, 255, 256, 65535, 65536} { in := strings.Repeat("x", n) b, err := msgpack.Marshal(in) if err != nil { t.Fatal(err) } var out string err = msgpack.Unmarshal(b, &out) if err != nil { t.Fatal(err) } if out != in { t.Fatalf("%q != %q", out, in) } } }