pax_global_header00006660000000000000000000000064141345102530014510gustar00rootroot0000000000000052 comment=9f30401e9cdcc6fa561d6b3e4982cbe8161f1086 msgpack-5.3.5/000077500000000000000000000000001413451025300131475ustar00rootroot00000000000000msgpack-5.3.5/.github/000077500000000000000000000000001413451025300145075ustar00rootroot00000000000000msgpack-5.3.5/.github/FUNDING.yml000066400000000000000000000000401413451025300163160ustar00rootroot00000000000000custom: ['https://uptrace.dev'] msgpack-5.3.5/.github/ISSUE_TEMPLATE/000077500000000000000000000000001413451025300166725ustar00rootroot00000000000000msgpack-5.3.5/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000023701413451025300213660ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve title: '' labels: '' assignees: '' --- Issue tracker is used for reporting bugs and discussing new features. Please use [Discord](https://discord.gg/rWtp5Aj) or [stackoverflow](https://stackoverflow.com) for supporting issues. ## Expected Behavior ## Current Behavior ## Possible Solution ## Steps to Reproduce 1. 2. 3. 4. ## Context (Environment) ## Detailed Description ## Possible Implementation msgpack-5.3.5/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000002061413451025300206600ustar00rootroot00000000000000blank_issues_enabled: false contact_links: - name: Discord url: https://discord.gg/rWtp5Aj about: Ask a question at Discord msgpack-5.3.5/.github/workflows/000077500000000000000000000000001413451025300165445ustar00rootroot00000000000000msgpack-5.3.5/.github/workflows/build.yml000066400000000000000000000007131413451025300203670ustar00rootroot00000000000000name: Go on: push: branches: [v5] pull_request: branches: [v5] jobs: build: name: build runs-on: ubuntu-latest strategy: matrix: go-version: [1.16.x, 1.17.x] steps: - name: Set up ${{ matrix.go-version }} uses: actions/setup-go@v2 with: go-version: ${{ matrix.go-version }} - name: Checkout code uses: actions/checkout@v2 - name: Test run: make test msgpack-5.3.5/.github/workflows/commitlint.yml000066400000000000000000000003431413451025300214460ustar00rootroot00000000000000name: Lint Commit Messages on: [pull_request] jobs: commitlint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - uses: wagoid/commitlint-github-action@v4 msgpack-5.3.5/.prettierrc000066400000000000000000000001001413451025300153220ustar00rootroot00000000000000semi: false singleQuote: true proseWrap: always printWidth: 100 msgpack-5.3.5/.travis.yml000066400000000000000000000005001413451025300152530ustar00rootroot00000000000000sudo: false language: go go: - 1.15.x - 1.16.x - tip matrix: allow_failures: - go: tip env: - GO111MODULE=on go_import_path: github.com/vmihailenco/msgpack before_install: - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.31.0 msgpack-5.3.5/CHANGELOG.md000066400000000000000000000033501413451025300147610ustar00rootroot00000000000000## [5.3.5](https://github.com/vmihailenco/msgpack/compare/v5.3.4...v5.3.5) (2021-10-22) ## v5 ### Added - `DecodeMap` is split into `DecodeMap`, `DecodeTypedMap`, and `DecodeUntypedMap`. - New msgpack extensions API. ### Changed - `Reset*` functions also reset flags. - `SetMapDecodeFunc` is renamed to `SetMapDecoder`. - `StructAsArray` is renamed to `UseArrayEncodedStructs`. - `SortMapKeys` is renamed to `SetSortMapKeys`. ### Removed - `UseJSONTag` is removed. Use `SetCustomStructTag("json")` instead. ## v4 - Encode, Decode, Marshal, and Unmarshal are changed to accept single argument. EncodeMulti and DecodeMulti are added as replacement. - Added EncodeInt8/16/32/64 and EncodeUint8/16/32/64. - Encoder changed to preserve type of numbers instead of chosing most compact encoding. The old behavior can be achieved with Encoder.UseCompactEncoding. ## v3.3 - `msgpack:",inline"` tag is restored to force inlining structs. ## v3.2 - Decoding extension types returns pointer to the value instead of the value. Fixes #153 ## 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-5.3.5/LICENSE000066400000000000000000000024531413451025300141600ustar00rootroot00000000000000Copyright (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-5.3.5/Makefile000066400000000000000000000002161413451025300146060ustar00rootroot00000000000000test: go test ./... go test ./... -short -race go test ./... -run=NONE -bench=. -benchmem env GOOS=linux GOARCH=386 go test ./... go vet msgpack-5.3.5/README.md000066400000000000000000000065761413451025300144440ustar00rootroot00000000000000# MessagePack encoding for Golang [![Build Status](https://travis-ci.org/vmihailenco/msgpack.svg)](https://travis-ci.org/vmihailenco/msgpack) [![PkgGoDev](https://pkg.go.dev/badge/github.com/vmihailenco/msgpack/v5)](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5) [![Documentation](https://img.shields.io/badge/msgpack-documentation-informational)](https://msgpack.uptrace.dev/) [![Chat](https://discordapp.com/api/guilds/752070105847955518/widget.png)](https://discord.gg/rWtp5Aj) > :heart: > [**Uptrace.dev** - All-in-one tool to optimize performance and monitor errors & logs](https://uptrace.dev/?utm_source=gh-msgpack&utm_campaign=gh-msgpack-var2) - Join [Discord](https://discord.gg/rWtp5Aj) to ask questions. - [Documentation](https://msgpack.uptrace.dev) - [Reference](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5) - [Examples](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#pkg-examples) Other projects you may like: - [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite. - [BunRouter](https://bunrouter.uptrace.dev/) - fast and flexible HTTP router for Go. ## Features - Primitives, arrays, maps, structs, time.Time and interface{}. - Appengine \*datastore.Key and datastore.Cursor. - [CustomEncoder]/[CustomDecoder] interfaces for custom encoding. - [Extensions](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#example-RegisterExt) to encode type information. - Renaming fields via `msgpack:"my_field_name"` and alias via `msgpack:"alias:another_name"`. - Omitting individual empty fields via `msgpack:",omitempty"` tag or all [empty fields in a struct](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#example-Marshal-OmitEmpty). - [Map keys sorting](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#Encoder.SetSortMapKeys). - Encoding/decoding all [structs as arrays](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#Encoder.UseArrayEncodedStructs) or [individual structs](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#example-Marshal-AsArray). - [Encoder.SetCustomStructTag] with [Decoder.SetCustomStructTag] can turn msgpack into drop-in replacement for any tag. - Simple but very fast and efficient [queries](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#example-Decoder.Query). [customencoder]: https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#CustomEncoder [customdecoder]: https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#CustomDecoder [encoder.setcustomstructtag]: https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#Encoder.SetCustomStructTag [decoder.setcustomstructtag]: https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#Decoder.SetCustomStructTag ## Installation msgpack supports 2 last Go versions and requires support for [Go modules](https://github.com/golang/go/wiki/Modules). So make sure to initialize a Go module: ```shell go mod init github.com/my/repo ``` And then install msgpack/v5 (note _v5_ in the import; omitting it is a popular mistake): ```shell go get github.com/vmihailenco/msgpack/v5 ``` ## Quickstart ```go import "github.com/vmihailenco/msgpack/v5" 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 } ``` msgpack-5.3.5/bench_test.go000066400000000000000000000164371413451025300156270ustar00rootroot00000000000000package msgpack_test import ( "bytes" "encoding/json" "io/ioutil" "math" "testing" "time" "github.com/vmihailenco/msgpack/v5" ) func BenchmarkDiscard(b *testing.B) { enc := msgpack.NewEncoder(ioutil.Discard) b.ResetTimer() for i := 0; i < b.N; i++ { if err := enc.Encode(nil); err != nil { b.Fatal(err) } if err := enc.Encode("hello"); err != nil { b.Fatal(err) } } } func benchmarkEncodeDecode(b *testing.B, src, dst interface{}) { var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) dec := msgpack.NewDecoder(&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 benchmarkJSONEncodeDecode(b *testing.B, src, dst interface{}) { var buf bytes.Buffer enc := json.NewEncoder(&buf) dec := json.NewDecoder(&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 BenchmarkFloat32(b *testing.B) { var dst float32 benchmarkEncodeDecode(b, float32(0), &dst) } func BenchmarkFloat32_Max(b *testing.B) { var dst float32 benchmarkEncodeDecode(b, float32(math.MaxFloat32), &dst) } func BenchmarkFloat64(b *testing.B) { var dst float64 benchmarkEncodeDecode(b, float64(0), &dst) } func BenchmarkFloat64_Max(b *testing.B) { var dst float64 benchmarkEncodeDecode(b, float64(math.MaxFloat64), &dst) } 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 BenchmarkByteArrayPtr(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", } dst := new(map[string]string) benchmarkEncodeDecode(b, src, &dst) } func BenchmarkMapStringInterfaceMsgpack(b *testing.B) { src := map[string]interface{}{ "hello": "world", "foo": "bar", "one": 1111111, "two": 2222222, } var dst map[string]interface{} benchmarkEncodeDecode(b, src, &dst) } func BenchmarkMapStringInterfaceJSON(b *testing.B) { src := map[string]interface{}{ "hello": "world", "foo": "bar", "one": 1111111, "two": 2222222, } var dst map[string]interface{} benchmarkJSONEncodeDecode(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) _ msgpack.CustomDecoder = (*benchmarkStruct2)(nil) ) func (s *benchmarkStruct2) EncodeMsgpack(enc *msgpack.Encoder) error { return enc.EncodeMulti( s.Name, s.Colors, s.Age, s.Data, s.CreatedAt, s.UpdatedAt, ) } func (s *benchmarkStruct2) DecodeMsgpack(dec *msgpack.Decoder) error { return dec.DecodeMulti( &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) } } } type benchmarkStructPartially struct { Name string Age int } func BenchmarkStructUnmarshalPartially(b *testing.B) { in := structForBenchmark() buf, err := msgpack.Marshal(in) if err != nil { b.Fatal(err) } out := new(benchmarkStructPartially) b.ResetTimer() for i := 0; i < b.N; i++ { err = msgpack.Unmarshal(buf, out) if 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": int64(i), "attrs": map[string]interface{}{"phone": int64(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].(int64) != 10 { b.Fatalf("%v != %d", values[0], 10) } } } msgpack-5.3.5/commitlint.config.js000066400000000000000000000001021413451025300171210ustar00rootroot00000000000000module.exports = { extends: ['@commitlint/config-conventional'] } msgpack-5.3.5/decode.go000066400000000000000000000335651413451025300147350ustar00rootroot00000000000000package msgpack import ( "bufio" "bytes" "errors" "fmt" "io" "reflect" "sync" "time" "github.com/vmihailenco/msgpack/v5/msgpcode" ) const ( looseInterfaceDecodingFlag uint32 = 1 << iota disallowUnknownFieldsFlag ) const ( bytesAllocLimit = 1e6 // 1mb sliceAllocLimit = 1e4 maxMapSize = 1e6 ) type bufReader interface { io.Reader io.ByteScanner } //------------------------------------------------------------------------------ var decPool = sync.Pool{ New: func() interface{} { return NewDecoder(nil) }, } func GetDecoder() *Decoder { return decPool.Get().(*Decoder) } func PutDecoder(dec *Decoder) { dec.r = nil dec.s = nil decPool.Put(dec) } //------------------------------------------------------------------------------ // Unmarshal decodes the MessagePack-encoded data and stores the result // in the value pointed to by v. func Unmarshal(data []byte, v interface{}) error { dec := GetDecoder() dec.Reset(bytes.NewReader(data)) err := dec.Decode(v) PutDecoder(dec) return err } // A Decoder reads and decodes MessagePack values from an input stream. type Decoder struct { r io.Reader s io.ByteScanner buf []byte rec []byte // accumulates read data if not nil dict []string flags uint32 structTag string mapDecoder func(*Decoder) (interface{}, error) } // NewDecoder returns a new decoder that reads from r. // // The decoder introduces its own buffering and may read data from r // beyond the requested msgpack values. Buffering can be disabled // by passing a reader that implements io.ByteScanner interface. func NewDecoder(r io.Reader) *Decoder { d := new(Decoder) d.Reset(r) return d } // Reset discards any buffered data, resets all state, and switches the buffered // reader to read from r. func (d *Decoder) Reset(r io.Reader) { d.ResetDict(r, nil) } // ResetDict is like Reset, but also resets the dict. func (d *Decoder) ResetDict(r io.Reader, dict []string) { d.resetReader(r) d.flags = 0 d.structTag = "" d.mapDecoder = nil d.dict = dict } func (d *Decoder) WithDict(dict []string, fn func(*Decoder) error) error { oldDict := d.dict d.dict = dict err := fn(d) d.dict = oldDict return err } func (d *Decoder) resetReader(r io.Reader) { if br, ok := r.(bufReader); ok { d.r = br d.s = br } else { br := bufio.NewReader(r) d.r = br d.s = br } } func (d *Decoder) SetMapDecoder(fn func(*Decoder) (interface{}, error)) { d.mapDecoder = fn } // UseLooseInterfaceDecoding causes decoder to use DecodeInterfaceLoose // to decode msgpack value into Go interface{}. func (d *Decoder) UseLooseInterfaceDecoding(on bool) { if on { d.flags |= looseInterfaceDecodingFlag } else { d.flags &= ^looseInterfaceDecodingFlag } } // SetCustomStructTag causes the decoder to use the supplied tag as a fallback option // if there is no msgpack tag. func (d *Decoder) SetCustomStructTag(tag string) { d.structTag = tag } // DisallowUnknownFields causes the Decoder to return an error when the destination // is a struct and the input contains object keys which do not match any // non-ignored, exported fields in the destination. func (d *Decoder) DisallowUnknownFields(on bool) { if on { d.flags |= disallowUnknownFieldsFlag } else { d.flags &= ^disallowUnknownFieldsFlag } } // UseInternedStrings enables support for decoding interned strings. func (d *Decoder) UseInternedStrings(on bool) { if on { d.flags |= useInternedStringsFlag } else { d.flags &= ^useInternedStringsFlag } } // Buffered returns a reader of the data remaining in the Decoder's buffer. // The reader is valid until the next call to Decode. func (d *Decoder) Buffered() io.Reader { return d.r } //nolint:gocyclo func (d *Decoder) Decode(v interface{}) error { var err error switch v := v.(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 } } vv := reflect.ValueOf(v) if !vv.IsValid() { return errors.New("msgpack: Decode(nil)") } if vv.Kind() != reflect.Ptr { return fmt.Errorf("msgpack: Decode(non-pointer %T)", v) } if vv.IsNil() { return fmt.Errorf("msgpack: Decode(non-settable %T)", v) } vv = vv.Elem() if vv.Kind() == reflect.Interface { if !vv.IsNil() { vv = vv.Elem() if vv.Kind() != reflect.Ptr { return fmt.Errorf("msgpack: Decode(non-pointer %s)", vv.Type().String()) } } } return d.DecodeValue(vv) } func (d *Decoder) DecodeMulti(v ...interface{}) error { for _, vv := range v { if err := d.Decode(vv); err != nil { return err } } return nil } func (d *Decoder) decodeInterfaceCond() (interface{}, error) { if d.flags&looseInterfaceDecodingFlag != 0 { return d.DecodeInterfaceLoose() } return d.DecodeInterface() } 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 != msgpcode.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 byte) (bool, error) { if c == msgpcode.Nil { return false, nil } if c == msgpcode.False { return false, nil } if c == msgpcode.True { return true, nil } return false, fmt.Errorf("msgpack: invalid code=%x decoding bool", c) } func (d *Decoder) DecodeDuration() (time.Duration, error) { n, err := d.DecodeInt64() if err != nil { return 0, err } return time.Duration(n), nil } // DecodeInterface decodes value into interface. It returns following types: // - nil, // - bool, // - int8, int16, int32, int64, // - uint8, uint16, uint32, uint64, // - float32 and float64, // - string, // - []byte, // - slices of any of the above, // - maps of any of the above. // // DecodeInterface should be used only when you don't know the type of value // you are decoding. For example, if you are decoding number it is better to use // DecodeInt64 for negative numbers and DecodeUint64 for positive numbers. func (d *Decoder) DecodeInterface() (interface{}, error) { c, err := d.readCode() if err != nil { return nil, err } if msgpcode.IsFixedNum(c) { return int8(c), nil } if msgpcode.IsFixedMap(c) { err = d.s.UnreadByte() if err != nil { return nil, err } return d.decodeMapDefault() } if msgpcode.IsFixedArray(c) { return d.decodeSlice(c) } if msgpcode.IsFixedString(c) { return d.string(c) } switch c { case msgpcode.Nil: return nil, nil case msgpcode.False, msgpcode.True: return d.bool(c) case msgpcode.Float: return d.float32(c) case msgpcode.Double: return d.float64(c) case msgpcode.Uint8: return d.uint8() case msgpcode.Uint16: return d.uint16() case msgpcode.Uint32: return d.uint32() case msgpcode.Uint64: return d.uint64() case msgpcode.Int8: return d.int8() case msgpcode.Int16: return d.int16() case msgpcode.Int32: return d.int32() case msgpcode.Int64: return d.int64() case msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32: return d.bytes(c, nil) case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32: return d.string(c) case msgpcode.Array16, msgpcode.Array32: return d.decodeSlice(c) case msgpcode.Map16, msgpcode.Map32: err = d.s.UnreadByte() if err != nil { return nil, err } return d.decodeMapDefault() case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4, msgpcode.FixExt8, msgpcode.FixExt16, msgpcode.Ext8, msgpcode.Ext16, msgpcode.Ext32: return d.decodeInterfaceExt(c) } return 0, fmt.Errorf("msgpack: unknown code %x decoding interface{}", c) } // DecodeInterfaceLoose is like DecodeInterface except that: // - int8, int16, and int32 are converted to int64, // - uint8, uint16, and uint32 are converted to uint64, // - float32 is converted to float64. // - []byte is converted to string. func (d *Decoder) DecodeInterfaceLoose() (interface{}, error) { c, err := d.readCode() if err != nil { return nil, err } if msgpcode.IsFixedNum(c) { return int64(int8(c)), nil } if msgpcode.IsFixedMap(c) { err = d.s.UnreadByte() if err != nil { return nil, err } return d.decodeMapDefault() } if msgpcode.IsFixedArray(c) { return d.decodeSlice(c) } if msgpcode.IsFixedString(c) { return d.string(c) } switch c { case msgpcode.Nil: return nil, nil case msgpcode.False, msgpcode.True: return d.bool(c) case msgpcode.Float, msgpcode.Double: return d.float64(c) case msgpcode.Uint8, msgpcode.Uint16, msgpcode.Uint32, msgpcode.Uint64: return d.uint(c) case msgpcode.Int8, msgpcode.Int16, msgpcode.Int32, msgpcode.Int64: return d.int(c) case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32, msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32: return d.string(c) case msgpcode.Array16, msgpcode.Array32: return d.decodeSlice(c) case msgpcode.Map16, msgpcode.Map32: err = d.s.UnreadByte() if err != nil { return nil, err } return d.decodeMapDefault() case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4, msgpcode.FixExt8, msgpcode.FixExt16, msgpcode.Ext8, msgpcode.Ext16, msgpcode.Ext32: return d.decodeInterfaceExt(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 msgpcode.IsFixedNum(c) { return nil } if msgpcode.IsFixedMap(c) { return d.skipMap(c) } if msgpcode.IsFixedArray(c) { return d.skipSlice(c) } if msgpcode.IsFixedString(c) { return d.skipBytes(c) } switch c { case msgpcode.Nil, msgpcode.False, msgpcode.True: return nil case msgpcode.Uint8, msgpcode.Int8: return d.skipN(1) case msgpcode.Uint16, msgpcode.Int16: return d.skipN(2) case msgpcode.Uint32, msgpcode.Int32, msgpcode.Float: return d.skipN(4) case msgpcode.Uint64, msgpcode.Int64, msgpcode.Double: return d.skipN(8) case msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32: return d.skipBytes(c) case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32: return d.skipBytes(c) case msgpcode.Array16, msgpcode.Array32: return d.skipSlice(c) case msgpcode.Map16, msgpcode.Map32: return d.skipMap(c) case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4, msgpcode.FixExt8, msgpcode.FixExt16, msgpcode.Ext8, msgpcode.Ext16, msgpcode.Ext32: return d.skipExt(c) } return fmt.Errorf("msgpack: unknown code %x", c) } func (d *Decoder) DecodeRaw() (RawMessage, error) { d.rec = make([]byte, 0) if err := d.Skip(); err != nil { return nil, err } msg := RawMessage(d.rec) d.rec = nil return msg, nil } // PeekCode returns the next MessagePack code without advancing the reader. // Subpackage msgpack/codes defines the list of available msgpcode. func (d *Decoder) PeekCode() (byte, error) { c, err := d.s.ReadByte() if err != nil { return 0, err } return c, d.s.UnreadByte() } // ReadFull reads exactly len(buf) bytes into the buf. func (d *Decoder) ReadFull(buf []byte) error { _, err := readN(d.r, buf, len(buf)) return err } func (d *Decoder) hasNilCode() bool { code, err := d.PeekCode() return err == nil && code == msgpcode.Nil } func (d *Decoder) readCode() (byte, error) { c, err := d.s.ReadByte() if err != nil { return 0, err } if d.rec != nil { d.rec = append(d.rec, c) } return 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) { var err error d.buf, err = readN(d.r, d.buf, n) if err != nil { return nil, err } if d.rec != nil { // TODO: read directly into d.rec? d.rec = append(d.rec, d.buf...) } return d.buf, nil } func readN(r io.Reader, b []byte, n int) ([]byte, error) { if b == nil { if n == 0 { return make([]byte, 0), nil } switch { case n < 64: b = make([]byte, 0, 64) case n <= bytesAllocLimit: b = make([]byte, 0, n) default: b = make([]byte, 0, bytesAllocLimit) } } if n <= cap(b) { b = b[:n] _, err := io.ReadFull(r, b) return b, err } b = b[:cap(b)] var pos int for { alloc := min(n-len(b), bytesAllocLimit) b = append(b, make([]byte, alloc)...) _, err := io.ReadFull(r, b[pos:]) if err != nil { return b, err } if len(b) == n { break } pos = len(b) } return b, nil } func min(a, b int) int { //nolint:unparam if a <= b { return a } return b } msgpack-5.3.5/decode_map.go000066400000000000000000000143011413451025300155550ustar00rootroot00000000000000package msgpack import ( "errors" "fmt" "reflect" "github.com/vmihailenco/msgpack/v5/msgpcode" ) var errArrayStruct = errors.New("msgpack: number of fields in array-encoded struct has changed") var ( mapStringStringPtrType = reflect.TypeOf((*map[string]string)(nil)) mapStringStringType = mapStringStringPtrType.Elem() ) var ( mapStringInterfacePtrType = reflect.TypeOf((*map[string]interface{})(nil)) 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)) } if n == 0 { return nil } return d.decodeTypedMapValue(v, n) } func (d *Decoder) decodeMapDefault() (interface{}, error) { if d.mapDecoder != nil { return d.mapDecoder(d) } return d.DecodeMap() } // DecodeMapLen decodes map length. Length is -1 when map is nil. func (d *Decoder) DecodeMapLen() (int, error) { c, err := d.readCode() if err != nil { return 0, err } if msgpcode.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 byte) (int, error) { if c == msgpcode.Nil { return -1, nil } if c >= msgpcode.FixedMapLow && c <= msgpcode.FixedMapHigh { return int(c & msgpcode.FixedMapMask), nil } if c == msgpcode.Map16 { size, err := d.uint16() return int(size), err } if c == msgpcode.Map32 { size, err := d.uint32() return int(size), err } return 0, unexpectedCodeError{code: c, hint: "map length"} } 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 { size, err := d.DecodeMapLen() if err != nil { return err } if size == -1 { *ptr = nil return nil } m := *ptr if m == nil { *ptr = make(map[string]string, min(size, maxMapSize)) m = *ptr } for i := 0; i < size; 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 { m, err := d.DecodeMap() if err != nil { return err } *ptr = m return nil } func (d *Decoder) DecodeMap() (map[string]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, maxMapSize)) for i := 0; i < n; i++ { mk, err := d.DecodeString() if err != nil { return nil, err } mv, err := d.decodeInterfaceCond() if err != nil { return nil, err } m[mk] = mv } return m, nil } func (d *Decoder) DecodeUntypedMap() (map[interface{}]interface{}, error) { n, err := d.DecodeMapLen() if err != nil { return nil, err } if n == -1 { return nil, nil } m := make(map[interface{}]interface{}, min(n, maxMapSize)) for i := 0; i < n; i++ { mk, err := d.decodeInterfaceCond() if err != nil { return nil, err } mv, err := d.decodeInterfaceCond() if err != nil { return nil, err } m[mk] = mv } return m, nil } // DecodeTypedMap decodes a typed map. Typed map is a map that has a fixed type for keys and values. // Key and value types may be different. func (d *Decoder) DecodeTypedMap() (interface{}, error) { n, err := d.DecodeMapLen() if err != nil { return nil, err } if n <= 0 { return nil, nil } key, err := d.decodeInterfaceCond() if err != nil { return nil, err } value, err := d.decodeInterfaceCond() if err != nil { return nil, err } keyType := reflect.TypeOf(key) valueType := reflect.TypeOf(value) if !keyType.Comparable() { return nil, fmt.Errorf("msgpack: unsupported map key: %s", keyType.String()) } mapType := reflect.MapOf(keyType, valueType) mapValue := reflect.MakeMap(mapType) mapValue.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(value)) n-- if err := d.decodeTypedMapValue(mapValue, n); err != nil { return nil, err } return mapValue.Interface(), nil } func (d *Decoder) decodeTypedMapValue(v reflect.Value, n int) error { typ := v.Type() 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 (d *Decoder) skipMap(c byte) 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, v reflect.Value) error { c, err := d.readCode() if err != nil { return err } n, err := d.mapLen(c) if err == nil { return d.decodeStruct(v, n) } var err2 error n, err2 = d.arrayLen(c) if err2 != nil { return err } if n <= 0 { v.Set(reflect.Zero(v.Type())) return nil } fields := structs.Fields(v.Type(), d.structTag) if n != len(fields.List) { return errArrayStruct } for _, f := range fields.List { if err := f.DecodeValue(d, v); err != nil { return err } } return nil } func (d *Decoder) decodeStruct(v reflect.Value, n int) error { if n == -1 { v.Set(reflect.Zero(v.Type())) return nil } fields := structs.Fields(v.Type(), d.structTag) for i := 0; i < n; i++ { name, err := d.decodeStringTemp() if err != nil { return err } if f := fields.Map[name]; f != nil { if err := f.DecodeValue(d, v); err != nil { return err } continue } if d.flags&disallowUnknownFieldsFlag != 0 { return fmt.Errorf("msgpack: unknown field %q", name) } if err := d.Skip(); err != nil { return err } } return nil } msgpack-5.3.5/decode_number.go000066400000000000000000000131511413451025300162720ustar00rootroot00000000000000package msgpack import ( "fmt" "math" "reflect" "github.com/vmihailenco/msgpack/v5/msgpcode" ) 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 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 } // DecodeUint64 decodes msgpack int8/16/32/64 and uint8/16/32/64 // into Go uint64. 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 byte) (uint64, error) { if c == msgpcode.Nil { return 0, nil } if msgpcode.IsFixedNum(c) { return uint64(int8(c)), nil } switch c { case msgpcode.Uint8: n, err := d.uint8() return uint64(n), err case msgpcode.Int8: n, err := d.int8() return uint64(n), err case msgpcode.Uint16: n, err := d.uint16() return uint64(n), err case msgpcode.Int16: n, err := d.int16() return uint64(n), err case msgpcode.Uint32: n, err := d.uint32() return uint64(n), err case msgpcode.Int32: n, err := d.int32() return uint64(n), err case msgpcode.Uint64, msgpcode.Int64: return d.uint64() } return 0, fmt.Errorf("msgpack: invalid code=%x decoding uint64", c) } // DecodeInt64 decodes msgpack int8/16/32/64 and uint8/16/32/64 // into Go int64. 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 byte) (int64, error) { if c == msgpcode.Nil { return 0, nil } if msgpcode.IsFixedNum(c) { return int64(int8(c)), nil } switch c { case msgpcode.Uint8: n, err := d.uint8() return int64(n), err case msgpcode.Int8: n, err := d.uint8() return int64(int8(n)), err case msgpcode.Uint16: n, err := d.uint16() return int64(n), err case msgpcode.Int16: n, err := d.uint16() return int64(int16(n)), err case msgpcode.Uint32: n, err := d.uint32() return int64(n), err case msgpcode.Int32: n, err := d.uint32() return int64(int32(n)), err case msgpcode.Uint64, msgpcode.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 byte) (float32, error) { if c == msgpcode.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 } // DecodeFloat64 decodes msgpack float32/64 into Go float64. 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 byte) (float64, error) { switch c { case msgpcode.Float: n, err := d.float32(c) if err != nil { return 0, err } return float64(n), nil case msgpcode.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-5.3.5/decode_query.go000066400000000000000000000051761413451025300161570ustar00rootroot00000000000000package msgpack import ( "fmt" "strconv" "strings" "github.com/vmihailenco/msgpack/v5/msgpcode" ) 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.decodeInterfaceCond() 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 == msgpcode.Map16 || code == msgpcode.Map32 || msgpcode.IsFixedMap(code): err = d.queryMapKey(q) case code == msgpcode.Array16 || code == msgpcode.Array32 || msgpcode.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++ { key, err := d.decodeStringTemp() if err != nil { return err } if key == 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-5.3.5/decode_slice.go000066400000000000000000000065611413451025300161100ustar00rootroot00000000000000package msgpack import ( "fmt" "reflect" "github.com/vmihailenco/msgpack/v5/msgpcode" ) var sliceStringPtrType = reflect.TypeOf((*[]string)(nil)) // DecodeArrayLen decodes array length. Length is -1 when array is 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 byte) (int, error) { if c == msgpcode.Nil { return -1, nil } else if c >= msgpcode.FixedArrayLow && c <= msgpcode.FixedArrayHigh { return int(c & msgpcode.FixedArrayMask), nil } switch c { case msgpcode.Array16: n, err := d.uint16() return int(n), err case msgpcode.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 := makeStrings(*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 makeStrings(s []string, n int) []string { if n > sliceAllocLimit { n = sliceAllocLimit } 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)) } elem := v.Index(i) if err := d.DecodeValue(elem); err != nil { return err } } return nil } func growSliceValue(v reflect.Value, n int) reflect.Value { diff := n - v.Len() if diff > sliceAllocLimit { diff = sliceAllocLimit } 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 byte) ([]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, sliceAllocLimit)) for i := 0; i < n; i++ { v, err := d.decodeInterfaceCond() if err != nil { return nil, err } s = append(s, v) } return s, nil } func (d *Decoder) skipSlice(c byte) 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-5.3.5/decode_string.go000066400000000000000000000063201413451025300163100ustar00rootroot00000000000000package msgpack import ( "fmt" "reflect" "github.com/vmihailenco/msgpack/v5/msgpcode" ) func (d *Decoder) bytesLen(c byte) (int, error) { if c == msgpcode.Nil { return -1, nil } if msgpcode.IsFixedString(c) { return int(c & msgpcode.FixedStrMask), nil } switch c { case msgpcode.Str8, msgpcode.Bin8: n, err := d.uint8() return int(n), err case msgpcode.Str16, msgpcode.Bin16: n, err := d.uint16() return int(n), err case msgpcode.Str32, msgpcode.Bin32: n, err := d.uint32() return int(n), err } return 0, fmt.Errorf("msgpack: invalid code=%x decoding string/bytes length", c) } func (d *Decoder) DecodeString() (string, error) { if intern := d.flags&useInternedStringsFlag != 0; intern || len(d.dict) > 0 { return d.decodeInternedString(intern) } c, err := d.readCode() if err != nil { return "", err } return d.string(c) } func (d *Decoder) string(c byte) (string, error) { n, err := d.bytesLen(c) if err != nil { return "", err } return d.stringWithLen(n) } func (d *Decoder) stringWithLen(n int) (string, error) { if n <= 0 { 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 byte, 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) decodeStringTemp() (string, error) { if intern := d.flags&useInternedStringsFlag != 0; intern || len(d.dict) > 0 { return d.decodeInternedString(intern) } c, err := d.readCode() if err != nil { return "", err } n, err := d.bytesLen(c) if err != nil { return "", err } if n == -1 { return "", nil } b, err := d.readN(n) if err != nil { return "", err } return bytesToString(b), nil } 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 byte, 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 byte) error { n, err := d.bytesLen(c) if err != nil { return err } if n <= 0 { 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-5.3.5/decode_value.go000066400000000000000000000134771413451025300161310ustar00rootroot00000000000000package msgpack import ( "encoding" "errors" "fmt" "reflect" ) var ( interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() stringType = reflect.TypeOf((*string)(nil)).Elem() ) var valueDecoders []decoderFunc //nolint:gochecknoinits 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 { if v, ok := typeDecMap.Load(typ); ok { return v.(decoderFunc) } fn := _getDecoder(typ) typeDecMap.Store(typ, fn) return fn } func _getDecoder(typ reflect.Type) decoderFunc { kind := typ.Kind() if kind == reflect.Ptr { if _, ok := typeDecMap.Load(typ.Elem()); ok { return ptrValueDecoder(typ) } } if typ.Implements(customDecoderType) { return nilAwareDecoder(typ, decodeCustomValue) } if typ.Implements(unmarshalerType) { return nilAwareDecoder(typ, unmarshalValue) } if typ.Implements(binaryUnmarshalerType) { return nilAwareDecoder(typ, unmarshalBinaryValue) } if typ.Implements(textUnmarshalerType) { return nilAwareDecoder(typ, unmarshalTextValue) } // Addressable struct field value. if kind != reflect.Ptr { ptr := reflect.PtrTo(typ) if ptr.Implements(customDecoderType) { return addrDecoder(nilAwareDecoder(typ, decodeCustomValue)) } if ptr.Implements(unmarshalerType) { return addrDecoder(nilAwareDecoder(typ, unmarshalValue)) } if ptr.Implements(binaryUnmarshalerType) { return addrDecoder(nilAwareDecoder(typ, unmarshalBinaryValue)) } if ptr.Implements(textUnmarshalerType) { return addrDecoder(nilAwareDecoder(typ, unmarshalTextValue)) } } switch kind { case reflect.Ptr: return ptrValueDecoder(typ) case reflect.Slice: elem := typ.Elem() if elem.Kind() == reflect.Uint8 { return decodeBytesValue } if elem == 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 ptrValueDecoder(typ reflect.Type) decoderFunc { decoder := getDecoder(typ.Elem()) return func(d *Decoder, v reflect.Value) error { if d.hasNilCode() { if !v.IsNil() { v.Set(reflect.Zero(v.Type())) } return d.DecodeNil() } if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) } return decoder(d, v.Elem()) } } func addrDecoder(fn decoderFunc) decoderFunc { return func(d *Decoder, v reflect.Value) error { if !v.CanAddr() { return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface()) } return fn(d, v.Addr()) } } func nilAwareDecoder(typ reflect.Type, fn decoderFunc) decoderFunc { if nilable(typ.Kind()) { return func(d *Decoder, v reflect.Value) error { if d.hasNilCode() { return d.decodeNilValue(v) } if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) } return fn(d, v) } } return func(d *Decoder, v reflect.Value) error { if d.hasNilCode() { return d.decodeNilValue(v) } return fn(d, v) } } 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 (d *Decoder) interfaceValue(v reflect.Value) error { vv, err := d.decodeInterfaceCond() 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 } func decodeUnsupportedValue(d *Decoder, v reflect.Value) error { return fmt.Errorf("msgpack: Decode(unsupported %s)", v.Type()) } //------------------------------------------------------------------------------ func decodeCustomValue(d *Decoder, v reflect.Value) error { decoder := v.Interface().(CustomDecoder) return decoder.DecodeMsgpack(d) } func unmarshalValue(d *Decoder, v reflect.Value) error { var b []byte d.rec = make([]byte, 0, 64) if err := d.Skip(); err != nil { return err } b = d.rec d.rec = nil unmarshaler := v.Interface().(Unmarshaler) return unmarshaler.UnmarshalMsgpack(b) } func unmarshalBinaryValue(d *Decoder, v reflect.Value) error { data, err := d.DecodeBytes() if err != nil { return err } unmarshaler := v.Interface().(encoding.BinaryUnmarshaler) return unmarshaler.UnmarshalBinary(data) } func unmarshalTextValue(d *Decoder, v reflect.Value) error { data, err := d.DecodeBytes() if err != nil { return err } unmarshaler := v.Interface().(encoding.TextUnmarshaler) return unmarshaler.UnmarshalText(data) } msgpack-5.3.5/encode.go000066400000000000000000000122321413451025300147330ustar00rootroot00000000000000package msgpack import ( "bytes" "io" "reflect" "sync" "time" "github.com/vmihailenco/msgpack/v5/msgpcode" ) const ( sortMapKeysFlag uint32 = 1 << iota arrayEncodedStructsFlag useCompactIntsFlag useCompactFloatsFlag useInternedStringsFlag omitEmptyFlag ) type writer interface { io.Writer WriteByte(byte) error } type byteWriter struct { io.Writer } func newByteWriter(w io.Writer) byteWriter { return byteWriter{ Writer: w, } } func (bw byteWriter) WriteByte(c byte) error { _, err := bw.Write([]byte{c}) return err } //------------------------------------------------------------------------------ var encPool = sync.Pool{ New: func() interface{} { return NewEncoder(nil) }, } func GetEncoder() *Encoder { return encPool.Get().(*Encoder) } func PutEncoder(enc *Encoder) { enc.w = nil encPool.Put(enc) } // Marshal returns the MessagePack encoding of v. func Marshal(v interface{}) ([]byte, error) { enc := GetEncoder() var buf bytes.Buffer enc.Reset(&buf) err := enc.Encode(v) b := buf.Bytes() PutEncoder(enc) if err != nil { return nil, err } return b, err } type Encoder struct { w writer buf []byte timeBuf []byte dict map[string]int flags uint32 structTag string } // NewEncoder returns a new encoder that writes to w. func NewEncoder(w io.Writer) *Encoder { e := &Encoder{ buf: make([]byte, 9), } e.Reset(w) return e } // Writer returns the Encoder's writer. func (e *Encoder) Writer() io.Writer { return e.w } // Reset discards any buffered data, resets all state, and switches the writer to write to w. func (e *Encoder) Reset(w io.Writer) { e.ResetDict(w, nil) } // ResetDict is like Reset, but also resets the dict. func (e *Encoder) ResetDict(w io.Writer, dict map[string]int) { e.resetWriter(w) e.flags = 0 e.structTag = "" e.dict = dict } func (e *Encoder) WithDict(dict map[string]int, fn func(*Encoder) error) error { oldDict := e.dict e.dict = dict err := fn(e) e.dict = oldDict return err } func (e *Encoder) resetWriter(w io.Writer) { if bw, ok := w.(writer); ok { e.w = bw } else { e.w = newByteWriter(w) } } // SetSortMapKeys causes the Encoder to encode map keys in increasing order. // Supported map types are: // - map[string]string // - map[string]interface{} func (e *Encoder) SetSortMapKeys(on bool) *Encoder { if on { e.flags |= sortMapKeysFlag } else { e.flags &= ^sortMapKeysFlag } return e } // SetCustomStructTag causes the Encoder to use a custom struct tag as // fallback option if there is no msgpack tag. func (e *Encoder) SetCustomStructTag(tag string) { e.structTag = tag } // SetOmitEmpty causes the Encoder to omit empty values by default. func (e *Encoder) SetOmitEmpty(on bool) { if on { e.flags |= omitEmptyFlag } else { e.flags &= ^omitEmptyFlag } } // UseArrayEncodedStructs causes the Encoder to encode Go structs as msgpack arrays. func (e *Encoder) UseArrayEncodedStructs(on bool) { if on { e.flags |= arrayEncodedStructsFlag } else { e.flags &= ^arrayEncodedStructsFlag } } // UseCompactEncoding causes the Encoder to chose the most compact encoding. // For example, it allows to encode small Go int64 as msgpack int8 saving 7 bytes. func (e *Encoder) UseCompactInts(on bool) { if on { e.flags |= useCompactIntsFlag } else { e.flags &= ^useCompactIntsFlag } } // UseCompactFloats causes the Encoder to chose a compact integer encoding // for floats that can be represented as integers. func (e *Encoder) UseCompactFloats(on bool) { if on { e.flags |= useCompactFloatsFlag } else { e.flags &= ^useCompactFloatsFlag } } // UseInternedStrings causes the Encoder to intern strings. func (e *Encoder) UseInternedStrings(on bool) { if on { e.flags |= useInternedStringsFlag } else { e.flags &= ^useInternedStringsFlag } } 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.encodeInt64Cond(v) case uint: return e.EncodeUint(uint64(v)) case uint64: return e.encodeUint64Cond(v) case bool: return e.EncodeBool(v) case float32: return e.EncodeFloat32(v) case float64: return e.EncodeFloat64(v) case time.Duration: return e.encodeInt64Cond(int64(v)) case time.Time: return e.EncodeTime(v) } return e.EncodeValue(reflect.ValueOf(v)) } func (e *Encoder) EncodeMulti(v ...interface{}) error { for _, vv := range v { if err := e.Encode(vv); err != nil { return err } } return nil } func (e *Encoder) EncodeValue(v reflect.Value) error { fn := getEncoder(v.Type()) return fn(e, v) } func (e *Encoder) EncodeNil() error { return e.writeCode(msgpcode.Nil) } func (e *Encoder) EncodeBool(value bool) error { if value { return e.writeCode(msgpcode.True) } return e.writeCode(msgpcode.False) } func (e *Encoder) EncodeDuration(d time.Duration) error { return e.EncodeInt(int64(d)) } func (e *Encoder) writeCode(c byte) error { return e.w.WriteByte(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.Write(stringToBytes(s)) return err } msgpack-5.3.5/encode_map.go000066400000000000000000000066131413451025300155760ustar00rootroot00000000000000package msgpack import ( "math" "reflect" "sort" "github.com/vmihailenco/msgpack/v5/msgpcode" ) func encodeMapValue(e *Encoder, v reflect.Value) error { if v.IsNil() { return e.EncodeNil() } if err := e.EncodeMapLen(v.Len()); err != nil { return err } iter := v.MapRange() for iter.Next() { if err := e.EncodeValue(iter.Key()); err != nil { return err } if err := e.EncodeValue(iter.Value()); 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.flags&sortMapKeysFlag != 0 { 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() } m := v.Convert(mapStringInterfaceType).Interface().(map[string]interface{}) if e.flags&sortMapKeysFlag != 0 { return e.EncodeMapSorted(m) } return e.EncodeMap(m) } func (e *Encoder) EncodeMap(m map[string]interface{}) error { if m == nil { return e.EncodeNil() } if err := e.EncodeMapLen(len(m)); err != nil { return err } 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) EncodeMapSorted(m map[string]interface{}) error { if m == nil { return e.EncodeNil() } if err := e.EncodeMapLen(len(m)); err != nil { return err } keys := make([]string, 0, len(m)) for k := range m { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { if err := e.EncodeString(k); err != nil { return err } if err := e.Encode(m[k]); 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) EncodeMapLen(l int) error { if l < 16 { return e.writeCode(msgpcode.FixedMapLow | byte(l)) } if l <= math.MaxUint16 { return e.write2(msgpcode.Map16, uint16(l)) } return e.write4(msgpcode.Map32, uint32(l)) } func encodeStructValue(e *Encoder, strct reflect.Value) error { structFields := structs.Fields(strct.Type(), e.structTag) if e.flags&arrayEncodedStructsFlag != 0 || structFields.AsArray { return encodeStructValueAsArray(e, strct, structFields.List) } fields := structFields.OmitEmpty(strct, e.flags&omitEmptyFlag != 0) 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-5.3.5/encode_number.go000066400000000000000000000142221413451025300163040ustar00rootroot00000000000000package msgpack import ( "math" "reflect" "github.com/vmihailenco/msgpack/v5/msgpcode" ) // EncodeUint8 encodes an uint8 in 2 bytes preserving type of the number. func (e *Encoder) EncodeUint8(n uint8) error { return e.write1(msgpcode.Uint8, n) } func (e *Encoder) encodeUint8Cond(n uint8) error { if e.flags&useCompactIntsFlag != 0 { return e.EncodeUint(uint64(n)) } return e.EncodeUint8(n) } // EncodeUint16 encodes an uint16 in 3 bytes preserving type of the number. func (e *Encoder) EncodeUint16(n uint16) error { return e.write2(msgpcode.Uint16, n) } func (e *Encoder) encodeUint16Cond(n uint16) error { if e.flags&useCompactIntsFlag != 0 { return e.EncodeUint(uint64(n)) } return e.EncodeUint16(n) } // EncodeUint32 encodes an uint16 in 5 bytes preserving type of the number. func (e *Encoder) EncodeUint32(n uint32) error { return e.write4(msgpcode.Uint32, n) } func (e *Encoder) encodeUint32Cond(n uint32) error { if e.flags&useCompactIntsFlag != 0 { return e.EncodeUint(uint64(n)) } return e.EncodeUint32(n) } // EncodeUint64 encodes an uint16 in 9 bytes preserving type of the number. func (e *Encoder) EncodeUint64(n uint64) error { return e.write8(msgpcode.Uint64, n) } func (e *Encoder) encodeUint64Cond(n uint64) error { if e.flags&useCompactIntsFlag != 0 { return e.EncodeUint(n) } return e.EncodeUint64(n) } // EncodeInt8 encodes an int8 in 2 bytes preserving type of the number. func (e *Encoder) EncodeInt8(n int8) error { return e.write1(msgpcode.Int8, uint8(n)) } func (e *Encoder) encodeInt8Cond(n int8) error { if e.flags&useCompactIntsFlag != 0 { return e.EncodeInt(int64(n)) } return e.EncodeInt8(n) } // EncodeInt16 encodes an int16 in 3 bytes preserving type of the number. func (e *Encoder) EncodeInt16(n int16) error { return e.write2(msgpcode.Int16, uint16(n)) } func (e *Encoder) encodeInt16Cond(n int16) error { if e.flags&useCompactIntsFlag != 0 { return e.EncodeInt(int64(n)) } return e.EncodeInt16(n) } // EncodeInt32 encodes an int32 in 5 bytes preserving type of the number. func (e *Encoder) EncodeInt32(n int32) error { return e.write4(msgpcode.Int32, uint32(n)) } func (e *Encoder) encodeInt32Cond(n int32) error { if e.flags&useCompactIntsFlag != 0 { return e.EncodeInt(int64(n)) } return e.EncodeInt32(n) } // EncodeInt64 encodes an int64 in 9 bytes preserving type of the number. func (e *Encoder) EncodeInt64(n int64) error { return e.write8(msgpcode.Int64, uint64(n)) } func (e *Encoder) encodeInt64Cond(n int64) error { if e.flags&useCompactIntsFlag != 0 { return e.EncodeInt(n) } return e.EncodeInt64(n) } // EncodeUnsignedNumber encodes an uint64 in 1, 2, 3, 5, or 9 bytes. // Type of the number is lost during encoding. func (e *Encoder) EncodeUint(n uint64) error { if n <= math.MaxInt8 { return e.w.WriteByte(byte(n)) } if n <= math.MaxUint8 { return e.EncodeUint8(uint8(n)) } if n <= math.MaxUint16 { return e.EncodeUint16(uint16(n)) } if n <= math.MaxUint32 { return e.EncodeUint32(uint32(n)) } return e.EncodeUint64(n) } // EncodeNumber encodes an int64 in 1, 2, 3, 5, or 9 bytes. // Type of the number is lost during encoding. func (e *Encoder) EncodeInt(n int64) error { if n >= 0 { return e.EncodeUint(uint64(n)) } if n >= int64(int8(msgpcode.NegFixedNumLow)) { return e.w.WriteByte(byte(n)) } if n >= math.MinInt8 { return e.EncodeInt8(int8(n)) } if n >= math.MinInt16 { return e.EncodeInt16(int16(n)) } if n >= math.MinInt32 { return e.EncodeInt32(int32(n)) } return e.EncodeInt64(n) } func (e *Encoder) EncodeFloat32(n float32) error { if e.flags&useCompactFloatsFlag != 0 { if float32(int64(n)) == n { return e.EncodeInt(int64(n)) } } return e.write4(msgpcode.Float, math.Float32bits(n)) } func (e *Encoder) EncodeFloat64(n float64) error { if e.flags&useCompactFloatsFlag != 0 { // Both NaN and Inf convert to int64(-0x8000000000000000) // If n is NaN then it never compares true with any other value // If n is Inf then it doesn't convert from int64 back to +/-Inf // In both cases the comparison works. if float64(int64(n)) == n { return e.EncodeInt(int64(n)) } } return e.write8(msgpcode.Double, math.Float64bits(n)) } func (e *Encoder) write1(code byte, n uint8) error { e.buf = e.buf[:2] e.buf[0] = code e.buf[1] = n return e.write(e.buf) } func (e *Encoder) write2(code byte, n uint16) error { e.buf = e.buf[:3] e.buf[0] = code e.buf[1] = byte(n >> 8) e.buf[2] = byte(n) return e.write(e.buf) } func (e *Encoder) write4(code byte, n uint32) error { e.buf = e.buf[:5] e.buf[0] = 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 byte, n uint64) error { e.buf = e.buf[:9] e.buf[0] = 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 encodeUintValue(e *Encoder, v reflect.Value) error { return e.EncodeUint(v.Uint()) } func encodeIntValue(e *Encoder, v reflect.Value) error { return e.EncodeInt(v.Int()) } func encodeUint8CondValue(e *Encoder, v reflect.Value) error { return e.encodeUint8Cond(uint8(v.Uint())) } func encodeUint16CondValue(e *Encoder, v reflect.Value) error { return e.encodeUint16Cond(uint16(v.Uint())) } func encodeUint32CondValue(e *Encoder, v reflect.Value) error { return e.encodeUint32Cond(uint32(v.Uint())) } func encodeUint64CondValue(e *Encoder, v reflect.Value) error { return e.encodeUint64Cond(v.Uint()) } func encodeInt8CondValue(e *Encoder, v reflect.Value) error { return e.encodeInt8Cond(int8(v.Int())) } func encodeInt16CondValue(e *Encoder, v reflect.Value) error { return e.encodeInt16Cond(int16(v.Int())) } func encodeInt32CondValue(e *Encoder, v reflect.Value) error { return e.encodeInt32Cond(int32(v.Int())) } func encodeInt64CondValue(e *Encoder, v reflect.Value) error { return e.encodeInt64Cond(v.Int()) } 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-5.3.5/encode_slice.go000066400000000000000000000055341413451025300161210ustar00rootroot00000000000000package msgpack import ( "math" "reflect" "github.com/vmihailenco/msgpack/v5/msgpcode" ) var stringSliceType = reflect.TypeOf(([]string)(nil)) 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) } e.buf = grow(e.buf, v.Len()) reflect.Copy(reflect.ValueOf(e.buf), v) return e.write(e.buf) } func grow(b []byte, n int) []byte { if cap(b) >= n { return b[:n] } b = b[:cap(b)] b = append(b, make([]byte, n-len(b))...) return b } func (e *Encoder) EncodeBytesLen(l int) error { if l < 256 { return e.write1(msgpcode.Bin8, uint8(l)) } if l <= math.MaxUint16 { return e.write2(msgpcode.Bin16, uint16(l)) } return e.write4(msgpcode.Bin32, uint32(l)) } func (e *Encoder) encodeStringLen(l int) error { if l < 32 { return e.writeCode(msgpcode.FixedStrLow | byte(l)) } if l < 256 { return e.write1(msgpcode.Str8, uint8(l)) } if l <= math.MaxUint16 { return e.write2(msgpcode.Str16, uint16(l)) } return e.write4(msgpcode.Str32, uint32(l)) } func (e *Encoder) EncodeString(v string) error { if intern := e.flags&useInternedStringsFlag != 0; intern || len(e.dict) > 0 { return e.encodeInternedString(v, intern) } return e.encodeNormalString(v) } func (e *Encoder) encodeNormalString(v string) error { if err := e.encodeStringLen(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(msgpcode.FixedArrayLow | byte(l)) } if l <= math.MaxUint16 { return e.write2(msgpcode.Array16, uint16(l)) } return e.write4(msgpcode.Array32, uint32(l)) } func encodeStringSliceValue(e *Encoder, v reflect.Value) error { ss := v.Convert(stringSliceType).Interface().([]string) return e.encodeStringSlice(ss) } 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-5.3.5/encode_value.go000066400000000000000000000134561413451025300161400ustar00rootroot00000000000000package msgpack import ( "encoding" "fmt" "reflect" ) var valueEncoders []encoderFunc //nolint:gochecknoinits func init() { valueEncoders = []encoderFunc{ reflect.Bool: encodeBoolValue, reflect.Int: encodeIntValue, reflect.Int8: encodeInt8CondValue, reflect.Int16: encodeInt16CondValue, reflect.Int32: encodeInt32CondValue, reflect.Int64: encodeInt64CondValue, reflect.Uint: encodeUintValue, reflect.Uint8: encodeUint8CondValue, reflect.Uint16: encodeUint16CondValue, reflect.Uint32: encodeUint32CondValue, reflect.Uint64: encodeUint64CondValue, 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 v, ok := typeEncMap.Load(typ); ok { return v.(encoderFunc) } fn := _getEncoder(typ) typeEncMap.Store(typ, fn) return fn } func _getEncoder(typ reflect.Type) encoderFunc { kind := typ.Kind() if kind == reflect.Ptr { if _, ok := typeEncMap.Load(typ.Elem()); ok { return ptrEncoderFunc(typ) } } if typ.Implements(customEncoderType) { return encodeCustomValue } if typ.Implements(marshalerType) { return marshalValue } if typ.Implements(binaryMarshalerType) { return marshalBinaryValue } if typ.Implements(textMarshalerType) { return marshalTextValue } // 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 ptr.Implements(binaryMarshalerType) { return marshalBinaryValueAddr } if ptr.Implements(textMarshalerType) { return marshalTextValueAddr } } if typ == errorType { return encodeErrorValue } switch kind { case reflect.Ptr: return ptrEncoderFunc(typ) case reflect.Slice: elem := typ.Elem() if elem.Kind() == reflect.Uint8 { return encodeByteSliceValue } if elem == stringType { return encodeStringSliceValue } 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 { if nilable(v.Kind()) && 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 { if nilable(v.Kind()) && 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()) } func nilable(kind reflect.Kind) bool { switch kind { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: return true } return false } //------------------------------------------------------------------------------ func marshalBinaryValueAddr(e *Encoder, v reflect.Value) error { if !v.CanAddr() { return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface()) } return marshalBinaryValue(e, v.Addr()) } func marshalBinaryValue(e *Encoder, v reflect.Value) error { if nilable(v.Kind()) && v.IsNil() { return e.EncodeNil() } marshaler := v.Interface().(encoding.BinaryMarshaler) data, err := marshaler.MarshalBinary() if err != nil { return err } return e.EncodeBytes(data) } //------------------------------------------------------------------------------ func marshalTextValueAddr(e *Encoder, v reflect.Value) error { if !v.CanAddr() { return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface()) } return marshalTextValue(e, v.Addr()) } func marshalTextValue(e *Encoder, v reflect.Value) error { if nilable(v.Kind()) && v.IsNil() { return e.EncodeNil() } marshaler := v.Interface().(encoding.TextMarshaler) data, err := marshaler.MarshalText() if err != nil { return err } return e.EncodeBytes(data) } msgpack-5.3.5/example_CustomEncoder_test.go000066400000000000000000000013301413451025300210170ustar00rootroot00000000000000package msgpack_test import ( "fmt" "github.com/vmihailenco/msgpack/v5" ) 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.EncodeMulti(s.S, s.N) } func (s *customStruct) DecodeMsgpack(dec *msgpack.Decoder) error { return dec.DecodeMulti(&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-5.3.5/example_registerExt_test.go000066400000000000000000000075741413451025300205720ustar00rootroot00000000000000package msgpack_test import ( "encoding/binary" "fmt" "time" "github.com/vmihailenco/msgpack/v5" ) // https://github.com/fluent/fluentd/wiki/Forward-Protocol-Specification-v1#eventtime-ext-format type EventTime struct { time.Time } type OneMoreSecondEventTime struct { EventTime } var ( _ msgpack.Marshaler = (*EventTime)(nil) _ msgpack.Unmarshaler = (*EventTime)(nil) _ msgpack.Marshaler = (*OneMoreSecondEventTime)(nil) _ msgpack.Unmarshaler = (*OneMoreSecondEventTime)(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 (tm *OneMoreSecondEventTime) MarshalMsgpack() ([]byte, error) { b := make([]byte, 8) binary.BigEndian.PutUint32(b, uint32(tm.Unix()+1)) binary.BigEndian.PutUint32(b[4:], uint32(tm.Nanosecond())) return b, nil } func (tm *OneMoreSecondEventTime) 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+1), int64(usec)) return nil } func ExampleRegisterExt() { t := time.Unix(123456789, 123) { msgpack.RegisterExt(1, (*EventTime)(nil)) b, err := msgpack.Marshal(&EventTime{t}) if err != nil { panic(err) } var v interface{} err = msgpack.Unmarshal(b, &v) if err != nil { panic(err) } fmt.Println(v.(*EventTime).UTC()) tm := new(EventTime) err = msgpack.Unmarshal(b, &tm) if err != nil { panic(err) } fmt.Println(tm.UTC()) } { msgpack.RegisterExt(1, (*EventTime)(nil)) b, err := msgpack.Marshal(&EventTime{t}) if err != nil { panic(err) } // override ext msgpack.RegisterExt(1, (*OneMoreSecondEventTime)(nil)) var v interface{} err = msgpack.Unmarshal(b, &v) if err != nil { panic(err) } fmt.Println(v.(*OneMoreSecondEventTime).UTC()) } { msgpack.RegisterExt(1, (*OneMoreSecondEventTime)(nil)) b, err := msgpack.Marshal(&OneMoreSecondEventTime{ EventTime{t}, }) if err != nil { panic(err) } // override ext msgpack.RegisterExt(1, (*EventTime)(nil)) var v interface{} err = msgpack.Unmarshal(b, &v) if err != nil { panic(err) } fmt.Println(v.(*EventTime).UTC()) } // Output: 1973-11-29 21:33:09.000000123 +0000 UTC // 1973-11-29 21:33:09.000000123 +0000 UTC // 1973-11-29 21:33:10.000000123 +0000 UTC // 1973-11-29 21:33:10.000000123 +0000 UTC } func ExampleUnregisterExt() { t := time.Unix(123456789, 123) { msgpack.RegisterExt(1, (*EventTime)(nil)) b, err := msgpack.Marshal(&EventTime{t}) if err != nil { panic(err) } msgpack.UnregisterExt(1) var v interface{} err = msgpack.Unmarshal(b, &v) wanted := "msgpack: unknown ext id=1" if err.Error() != wanted { panic(err) } msgpack.RegisterExt(1, (*OneMoreSecondEventTime)(nil)) err = msgpack.Unmarshal(b, &v) if err != nil { panic(err) } fmt.Println(v.(*OneMoreSecondEventTime).UTC()) } { msgpack.RegisterExt(1, (*OneMoreSecondEventTime)(nil)) b, err := msgpack.Marshal(&OneMoreSecondEventTime{ EventTime{t}, }) if err != nil { panic(err) } msgpack.UnregisterExt(1) var v interface{} err = msgpack.Unmarshal(b, &v) wanted := "msgpack: unknown ext id=1" if err.Error() != wanted { panic(err) } msgpack.RegisterExt(1, (*EventTime)(nil)) err = msgpack.Unmarshal(b, &v) if err != nil { panic(err) } fmt.Println(v.(*EventTime).UTC()) } // Output: 1973-11-29 21:33:10.000000123 +0000 UTC // 1973-11-29 21:33:10.000000123 +0000 UTC } msgpack-5.3.5/example_test.go000066400000000000000000000100311413451025300161630ustar00rootroot00000000000000package msgpack_test import ( "bytes" "fmt" "github.com/vmihailenco/msgpack/v5" ) 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_SetMapDecoder() { 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) // Causes decoder to produce map[string]string instead of map[string]interface{}. dec.SetMapDecoder(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.Printf("%#v", out) // Output: map[string]string{"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_UseArrayEncodedStructs() { type Item struct { Foo string Bar string } var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) enc.UseArrayEncodedStructs(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:",as_array"` 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" } func ExampleMarshal_escapedNames() { og := map[string]interface{}{ "something:special": uint(123), "hello, world": "hello!", } raw, err := msgpack.Marshal(og) if err != nil { panic(err) } type Item struct { SomethingSpecial uint `msgpack:"'something:special'"` HelloWorld string `msgpack:"'hello, world'"` } var item Item if err := msgpack.Unmarshal(raw, &item); err != nil { panic(err) } fmt.Printf("%#v\n", item) //output: msgpack_test.Item{SomethingSpecial:0x7b, HelloWorld:"hello!"} } msgpack-5.3.5/ext.go000066400000000000000000000142041413451025300142770ustar00rootroot00000000000000package msgpack import ( "fmt" "math" "reflect" "github.com/vmihailenco/msgpack/v5/msgpcode" ) type extInfo struct { Type reflect.Type Decoder func(d *Decoder, v reflect.Value, extLen int) error } var extTypes = make(map[int8]*extInfo) type MarshalerUnmarshaler interface { Marshaler Unmarshaler } func RegisterExt(extID int8, value MarshalerUnmarshaler) { RegisterExtEncoder(extID, value, func(e *Encoder, v reflect.Value) ([]byte, error) { marshaler := v.Interface().(Marshaler) return marshaler.MarshalMsgpack() }) RegisterExtDecoder(extID, value, func(d *Decoder, v reflect.Value, extLen int) error { b, err := d.readN(extLen) if err != nil { return err } return v.Interface().(Unmarshaler).UnmarshalMsgpack(b) }) } func UnregisterExt(extID int8) { unregisterExtEncoder(extID) unregisterExtDecoder(extID) } func RegisterExtEncoder( extID int8, value interface{}, encoder func(enc *Encoder, v reflect.Value) ([]byte, error), ) { unregisterExtEncoder(extID) typ := reflect.TypeOf(value) extEncoder := makeExtEncoder(extID, typ, encoder) typeEncMap.Store(extID, typ) typeEncMap.Store(typ, extEncoder) if typ.Kind() == reflect.Ptr { typeEncMap.Store(typ.Elem(), makeExtEncoderAddr(extEncoder)) } } func unregisterExtEncoder(extID int8) { t, ok := typeEncMap.Load(extID) if !ok { return } typeEncMap.Delete(extID) typ := t.(reflect.Type) typeEncMap.Delete(typ) if typ.Kind() == reflect.Ptr { typeEncMap.Delete(typ.Elem()) } } func makeExtEncoder( extID int8, typ reflect.Type, encoder func(enc *Encoder, v reflect.Value) ([]byte, error), ) encoderFunc { nilable := typ.Kind() == reflect.Ptr return func(e *Encoder, v reflect.Value) error { if nilable && v.IsNil() { return e.EncodeNil() } b, err := encoder(e, v) if err != nil { return err } if err := e.EncodeExtHeader(extID, len(b)); err != nil { return err } return e.write(b) } } func makeExtEncoderAddr(extEncoder encoderFunc) encoderFunc { return func(e *Encoder, v reflect.Value) error { if !v.CanAddr() { return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface()) } return extEncoder(e, v.Addr()) } } func RegisterExtDecoder( extID int8, value interface{}, decoder func(dec *Decoder, v reflect.Value, extLen int) error, ) { unregisterExtDecoder(extID) typ := reflect.TypeOf(value) extDecoder := makeExtDecoder(extID, typ, decoder) extTypes[extID] = &extInfo{ Type: typ, Decoder: decoder, } typeDecMap.Store(extID, typ) typeDecMap.Store(typ, extDecoder) if typ.Kind() == reflect.Ptr { typeDecMap.Store(typ.Elem(), makeExtDecoderAddr(extDecoder)) } } func unregisterExtDecoder(extID int8) { t, ok := typeDecMap.Load(extID) if !ok { return } typeDecMap.Delete(extID) delete(extTypes, extID) typ := t.(reflect.Type) typeDecMap.Delete(typ) if typ.Kind() == reflect.Ptr { typeDecMap.Delete(typ.Elem()) } } func makeExtDecoder( wantedExtID int8, typ reflect.Type, decoder func(d *Decoder, v reflect.Value, extLen int) error, ) decoderFunc { return nilAwareDecoder(typ, func(d *Decoder, v reflect.Value) error { extID, extLen, err := d.DecodeExtHeader() if err != nil { return err } if extID != wantedExtID { return fmt.Errorf("msgpack: got ext type=%d, wanted %d", extID, wantedExtID) } return decoder(d, v, extLen) }) } func makeExtDecoderAddr(extDecoder decoderFunc) decoderFunc { return func(d *Decoder, v reflect.Value) error { if !v.CanAddr() { return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface()) } return extDecoder(d, v.Addr()) } } func (e *Encoder) EncodeExtHeader(extID int8, extLen int) error { if err := e.encodeExtLen(extLen); err != nil { return err } if err := e.w.WriteByte(byte(extID)); err != nil { return err } return nil } func (e *Encoder) encodeExtLen(l int) error { switch l { case 1: return e.writeCode(msgpcode.FixExt1) case 2: return e.writeCode(msgpcode.FixExt2) case 4: return e.writeCode(msgpcode.FixExt4) case 8: return e.writeCode(msgpcode.FixExt8) case 16: return e.writeCode(msgpcode.FixExt16) } if l <= math.MaxUint8 { return e.write1(msgpcode.Ext8, uint8(l)) } if l <= math.MaxUint16 { return e.write2(msgpcode.Ext16, uint16(l)) } return e.write4(msgpcode.Ext32, uint32(l)) } func (d *Decoder) DecodeExtHeader() (extID int8, extLen int, err error) { c, err := d.readCode() if err != nil { return } return d.extHeader(c) } func (d *Decoder) extHeader(c byte) (int8, int, error) { extLen, err := d.parseExtLen(c) if err != nil { return 0, 0, err } extID, err := d.readCode() if err != nil { return 0, 0, err } return int8(extID), extLen, nil } func (d *Decoder) parseExtLen(c byte) (int, error) { switch c { case msgpcode.FixExt1: return 1, nil case msgpcode.FixExt2: return 2, nil case msgpcode.FixExt4: return 4, nil case msgpcode.FixExt8: return 8, nil case msgpcode.FixExt16: return 16, nil case msgpcode.Ext8: n, err := d.uint8() return int(n), err case msgpcode.Ext16: n, err := d.uint16() return int(n), err case msgpcode.Ext32: n, err := d.uint32() return int(n), err default: return 0, fmt.Errorf("msgpack: invalid code=%x decoding ext len", c) } } func (d *Decoder) decodeInterfaceExt(c byte) (interface{}, error) { extID, extLen, err := d.extHeader(c) if err != nil { return nil, err } info, ok := extTypes[extID] if !ok { return nil, fmt.Errorf("msgpack: unknown ext id=%d", extID) } v := reflect.New(info.Type).Elem() if nilable(v.Kind()) && v.IsNil() { v.Set(reflect.New(info.Type.Elem())) } if err := info.Decoder(d, v, extLen); err != nil { return nil, err } return v.Interface(), nil } func (d *Decoder) skipExt(c byte) error { n, err := d.parseExtLen(c) if err != nil { return err } return d.skipN(n + 1) } func (d *Decoder) skipExtHeader(c byte) 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 byte) int { switch c { case msgpcode.Ext8: return 1 case msgpcode.Ext16: return 2 case msgpcode.Ext32: return 4 } return 0 } msgpack-5.3.5/ext_test.go000066400000000000000000000063371413451025300153460ustar00rootroot00000000000000package msgpack_test import ( "bytes" "encoding/hex" "testing" "time" "github.com/stretchr/testify/require" "github.com/vmihailenco/msgpack/v5" "github.com/vmihailenco/msgpack/v5/msgpcode" ) func init() { msgpack.RegisterExt(9, (*ExtTest)(nil)) } type ExtTest struct { S string } var ( _ msgpack.Marshaler = (*ExtTest)(nil) _ msgpack.Unmarshaler = (*ExtTest)(nil) ) func (ext ExtTest) MarshalMsgpack() ([]byte, error) { return msgpack.Marshal("hello " + ext.S) } func (ext *ExtTest) UnmarshalMsgpack(b []byte) error { return msgpack.Unmarshal(b, &ext.S) } func TestEncodeDecodeExtHeader(t *testing.T) { v := &ExtTest{"world"} payload, err := v.MarshalMsgpack() require.Nil(t, err) var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) err = enc.EncodeExtHeader(9, len(payload)) require.Nil(t, err) _, err = buf.Write(payload) require.Nil(t, err) var dst interface{} err = msgpack.Unmarshal(buf.Bytes(), &dst) require.Nil(t, err) v = dst.(*ExtTest) wanted := "hello world" require.Equal(t, v.S, wanted) dec := msgpack.NewDecoder(&buf) extID, extLen, err := dec.DecodeExtHeader() require.Nil(t, err) require.Equal(t, int8(9), extID) require.Equal(t, len(payload), extLen) data := make([]byte, extLen) err = dec.ReadFull(data) require.Nil(t, err) v = &ExtTest{} err = v.UnmarshalMsgpack(data) require.Nil(t, err) require.Equal(t, wanted, v.S) } func TestExt(t *testing.T) { v := &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) } ext := new(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(msgpcode.FixExt1), 2, 0} var dst interface{} err := msgpack.Unmarshal(b, &dst) if err == nil { t.Fatalf("got nil, wanted error") } got := err.Error() wanted := "msgpack: unknown ext id=2" if got != wanted { t.Fatalf("got %q, wanted %q", got, wanted) } } func TestSliceOfTime(t *testing.T) { in := []interface{}{time.Now()} b, err := msgpack.Marshal(in) if err != nil { t.Fatal(err) } var out []interface{} err = msgpack.Unmarshal(b, &out) if err != nil { t.Fatal(err) } outTime := out[0].(time.Time) inTime := in[0].(time.Time) if outTime.Unix() != inTime.Unix() { t.Fatalf("got %v, wanted %v", outTime, inTime) } } type customPayload struct { payload []byte } func (cp *customPayload) MarshalMsgpack() ([]byte, error) { return cp.payload, nil } func (cp *customPayload) UnmarshalMsgpack(b []byte) error { cp.payload = b return nil } func TestDecodeCustomPayload(t *testing.T) { b, err := hex.DecodeString("c70500c09eec3100") if err != nil { t.Fatal(err) } msgpack.RegisterExt(0, (*customPayload)(nil)) var cp *customPayload err = msgpack.Unmarshal(b, &cp) if err != nil { t.Fatal(err) } payload := hex.EncodeToString(cp.payload) wanted := "c09eec3100" if payload != wanted { t.Fatalf("got %q, wanted %q", payload, wanted) } } msgpack-5.3.5/extra/000077500000000000000000000000001413451025300142725ustar00rootroot00000000000000msgpack-5.3.5/extra/msgpappengine/000077500000000000000000000000001413451025300171275ustar00rootroot00000000000000msgpack-5.3.5/extra/msgpappengine/appengine.go000066400000000000000000000025621413451025300214310ustar00rootroot00000000000000package msgpappengine import ( "reflect" "github.com/vmihailenco/msgpack/v5" ds "google.golang.org/appengine/datastore" ) func init() { msgpack.Register((*ds.Key)(nil), encodeDatastoreKeyValue, decodeDatastoreKeyValue) msgpack.Register((*ds.Cursor)(nil), encodeDatastoreCursorValue, decodeDatastoreCursorValue) } func EncodeDatastoreKey(e *msgpack.Encoder, key *ds.Key) error { if key == nil { return e.EncodeNil() } return e.EncodeString(key.Encode()) } func encodeDatastoreKeyValue(e *msgpack.Encoder, v reflect.Value) error { key := v.Interface().(*ds.Key) return EncodeDatastoreKey(e, key) } func DecodeDatastoreKey(d *msgpack.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 *msgpack.Decoder, v reflect.Value) error { key, err := DecodeDatastoreKey(d) if err != nil { return err } v.Set(reflect.ValueOf(key)) return nil } func encodeDatastoreCursorValue(e *msgpack.Encoder, v reflect.Value) error { cursor := v.Interface().(ds.Cursor) return e.Encode(cursor.String()) } func decodeDatastoreCursorValue(d *msgpack.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-5.3.5/extra/msgpappengine/go.mod000066400000000000000000000003161413451025300202350ustar00rootroot00000000000000module github.com/vmihailenco/msgpack/extra/appengine go 1.15 replace github.com/vmihailenco/msgpack/v5 => ../.. require ( github.com/vmihailenco/msgpack/v5 v5.3.5 google.golang.org/appengine v1.6.7 ) msgpack-5.3.5/extra/msgpappengine/go.sum000066400000000000000000000043121413451025300202620ustar00rootroot00000000000000github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= msgpack-5.3.5/go.mod000066400000000000000000000002171413451025300142550ustar00rootroot00000000000000module github.com/vmihailenco/msgpack/v5 go 1.11 require ( github.com/stretchr/testify v1.6.1 github.com/vmihailenco/tagparser/v2 v2.0.0 ) msgpack-5.3.5/go.sum000066400000000000000000000022751413451025300143100ustar00rootroot00000000000000github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= msgpack-5.3.5/intern.go000066400000000000000000000116451413451025300150040ustar00rootroot00000000000000package msgpack import ( "fmt" "math" "reflect" "github.com/vmihailenco/msgpack/v5/msgpcode" ) const ( minInternedStringLen = 3 maxDictLen = math.MaxUint16 ) var internedStringExtID = int8(math.MinInt8) func init() { extTypes[internedStringExtID] = &extInfo{ Type: stringType, Decoder: decodeInternedStringExt, } } func decodeInternedStringExt(d *Decoder, v reflect.Value, extLen int) error { idx, err := d.decodeInternedStringIndex(extLen) if err != nil { return err } s, err := d.internedStringAtIndex(idx) if err != nil { return err } v.SetString(s) return nil } //------------------------------------------------------------------------------ func encodeInternedInterfaceValue(e *Encoder, v reflect.Value) error { if v.IsNil() { return e.EncodeNil() } v = v.Elem() if v.Kind() == reflect.String { return e.encodeInternedString(v.String(), true) } return e.EncodeValue(v) } func encodeInternedStringValue(e *Encoder, v reflect.Value) error { return e.encodeInternedString(v.String(), true) } func (e *Encoder) encodeInternedString(s string, intern bool) error { // Interned string takes at least 3 bytes. Plain string 1 byte + string len. if len(s) >= minInternedStringLen { if idx, ok := e.dict[s]; ok { return e.encodeInternedStringIndex(idx) } if intern && len(e.dict) < maxDictLen { if e.dict == nil { e.dict = make(map[string]int) } idx := len(e.dict) e.dict[s] = idx } } return e.encodeNormalString(s) } func (e *Encoder) encodeInternedStringIndex(idx int) error { if idx <= math.MaxUint8 { if err := e.writeCode(msgpcode.FixExt1); err != nil { return err } return e.write1(byte(internedStringExtID), uint8(idx)) } if idx <= math.MaxUint16 { if err := e.writeCode(msgpcode.FixExt2); err != nil { return err } return e.write2(byte(internedStringExtID), uint16(idx)) } if uint64(idx) <= math.MaxUint32 { if err := e.writeCode(msgpcode.FixExt4); err != nil { return err } return e.write4(byte(internedStringExtID), uint32(idx)) } return fmt.Errorf("msgpack: interned string index=%d is too large", idx) } //------------------------------------------------------------------------------ func decodeInternedInterfaceValue(d *Decoder, v reflect.Value) error { s, err := d.decodeInternedString(true) if err == nil { v.Set(reflect.ValueOf(s)) return nil } if err != nil { if _, ok := err.(unexpectedCodeError); !ok { return err } } if err := d.s.UnreadByte(); err != nil { return err } return decodeInterfaceValue(d, v) } func decodeInternedStringValue(d *Decoder, v reflect.Value) error { s, err := d.decodeInternedString(true) if err != nil { return err } v.SetString(s) return nil } func (d *Decoder) decodeInternedString(intern bool) (string, error) { c, err := d.readCode() if err != nil { return "", err } if msgpcode.IsFixedString(c) { n := int(c & msgpcode.FixedStrMask) return d.decodeInternedStringWithLen(n, intern) } switch c { case msgpcode.Nil: return "", nil case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4: typeID, extLen, err := d.extHeader(c) if err != nil { return "", err } if typeID != internedStringExtID { err := fmt.Errorf("msgpack: got ext type=%d, wanted %d", typeID, internedStringExtID) return "", err } idx, err := d.decodeInternedStringIndex(extLen) if err != nil { return "", err } return d.internedStringAtIndex(idx) case msgpcode.Str8, msgpcode.Bin8: n, err := d.uint8() if err != nil { return "", err } return d.decodeInternedStringWithLen(int(n), intern) case msgpcode.Str16, msgpcode.Bin16: n, err := d.uint16() if err != nil { return "", err } return d.decodeInternedStringWithLen(int(n), intern) case msgpcode.Str32, msgpcode.Bin32: n, err := d.uint32() if err != nil { return "", err } return d.decodeInternedStringWithLen(int(n), intern) } return "", unexpectedCodeError{ code: c, hint: "interned string", } } func (d *Decoder) decodeInternedStringIndex(extLen int) (int, error) { switch extLen { case 1: n, err := d.uint8() if err != nil { return 0, err } return int(n), nil case 2: n, err := d.uint16() if err != nil { return 0, err } return int(n), nil case 4: n, err := d.uint32() if err != nil { return 0, err } return int(n), nil } err := fmt.Errorf("msgpack: unsupported ext len=%d decoding interned string", extLen) return 0, err } func (d *Decoder) internedStringAtIndex(idx int) (string, error) { if idx >= len(d.dict) { err := fmt.Errorf("msgpack: interned string at index=%d does not exist", idx) return "", err } return d.dict[idx], nil } func (d *Decoder) decodeInternedStringWithLen(n int, intern bool) (string, error) { if n <= 0 { return "", nil } s, err := d.stringWithLen(n) if err != nil { return "", err } if intern && len(s) >= minInternedStringLen && len(d.dict) < maxDictLen { d.dict = append(d.dict, s) } return s, nil } msgpack-5.3.5/intern_test.go000066400000000000000000000053241413451025300160400ustar00rootroot00000000000000package msgpack_test import ( "bytes" "io" "testing" "github.com/stretchr/testify/require" "github.com/vmihailenco/msgpack/v5" ) type NoIntern struct { A string B string C interface{} } type Intern struct { A string `msgpack:",intern"` B string `msgpack:",intern"` C interface{} `msgpack:",intern"` } func TestInternedString(t *testing.T) { var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) enc.UseInternedStrings(true) dec := msgpack.NewDecoder(&buf) dec.UseInternedStrings(true) for i := 0; i < 3; i++ { err := enc.EncodeString("hello") require.Nil(t, err) } for i := 0; i < 3; i++ { s, err := dec.DecodeString() require.Nil(t, err) require.Equal(t, "hello", s) } err := enc.Encode("hello") require.Nil(t, err) v, err := dec.DecodeInterface() require.Nil(t, err) require.Equal(t, "hello", v) _, err = dec.DecodeInterface() require.Equal(t, io.EOF, err) } func TestInternedStringTag(t *testing.T) { var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) dec := msgpack.NewDecoder(&buf) in := []Intern{ {"f", "f", "f"}, {"fo", "fo", "fo"}, {"foo", "foo", "foo"}, {"f", "fo", "foo"}, } err := enc.Encode(in) require.Nil(t, err) var out []Intern err = dec.Decode(&out) require.Nil(t, err) require.Equal(t, in, out) } func TestResetDict(t *testing.T) { dict := []string{"hello world", "foo bar"} var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) dec := msgpack.NewDecoder(&buf) { enc.ResetDict(&buf, dictMap(dict)) err := enc.EncodeString("hello world") require.Nil(t, err) require.Equal(t, 3, buf.Len()) dec.ResetDict(&buf, dict) s, err := dec.DecodeString() require.Nil(t, err) require.Equal(t, "hello world", s) } { enc.ResetDict(&buf, dictMap(dict)) err := enc.Encode("foo bar") require.Nil(t, err) require.Equal(t, 3, buf.Len()) dec.ResetDict(&buf, dict) s, err := dec.DecodeInterface() require.Nil(t, err) require.Equal(t, "foo bar", s) } dec.ResetDict(&buf, dict) _ = enc.EncodeString("xxxx") require.Equal(t, 5, buf.Len()) _ = enc.Encode("xxxx") require.Equal(t, 10, buf.Len()) } func TestMapWithInternedString(t *testing.T) { type M map[string]interface{} dict := []string{"hello world", "foo bar"} var buf bytes.Buffer enc := msgpack.NewEncoder(nil) enc.ResetDict(&buf, dictMap(dict)) dec := msgpack.NewDecoder(nil) dec.ResetDict(&buf, dict) for i := 0; i < 100; i++ { in := M{ "foo bar": "hello world", "hello world": "foo bar", "foo": "bar", } err := enc.Encode(in) require.Nil(t, err) _, err = dec.DecodeInterface() require.Nil(t, err) } } func dictMap(dict []string) map[string]int { m := make(map[string]int, len(dict)) for i, s := range dict { m[s] = i } return m } msgpack-5.3.5/msgpack.go000066400000000000000000000017231413451025300151260ustar00rootroot00000000000000package msgpack import "fmt" type Marshaler interface { MarshalMsgpack() ([]byte, error) } type Unmarshaler interface { UnmarshalMsgpack([]byte) error } type CustomEncoder interface { EncodeMsgpack(*Encoder) error } type CustomDecoder interface { DecodeMsgpack(*Decoder) error } //------------------------------------------------------------------------------ type RawMessage []byte var ( _ CustomEncoder = (RawMessage)(nil) _ CustomDecoder = (*RawMessage)(nil) ) func (m RawMessage) EncodeMsgpack(enc *Encoder) error { return enc.write(m) } func (m *RawMessage) DecodeMsgpack(dec *Decoder) error { msg, err := dec.DecodeRaw() if err != nil { return err } *m = msg return nil } //------------------------------------------------------------------------------ type unexpectedCodeError struct { code byte hint string } func (err unexpectedCodeError) Error() string { return fmt.Sprintf("msgpack: unexpected code=%x decoding %s", err.code, err.hint) } msgpack-5.3.5/msgpack_test.go000066400000000000000000000223501413451025300161640ustar00rootroot00000000000000package msgpack_test import ( "bufio" "bytes" "fmt" "math" "reflect" "testing" "time" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "github.com/vmihailenco/msgpack/v5" ) type nameStruct struct { Name string } type MsgpackTest struct { suite.Suite buf *bytes.Buffer enc *msgpack.Encoder dec *msgpack.Decoder } func (t *MsgpackTest) SetUpTest() { t.buf = &bytes.Buffer{} t.enc = msgpack.NewEncoder(t.buf) t.dec = msgpack.NewDecoder(bufio.NewReader(t.buf)) } func (t *MsgpackTest) TestDecodeNil() { t.NotNil(t.dec.Decode(nil)) } func (t *MsgpackTest) TestTime() { in := time.Now() var out time.Time t.Nil(t.enc.Encode(in)) t.Nil(t.dec.Decode(&out)) t.True(out.Equal(in)) var zero time.Time t.Nil(t.enc.Encode(zero)) t.Nil(t.dec.Decode(&out)) t.True(out.Equal(zero)) t.True(out.IsZero()) } func (t *MsgpackTest) TestLargeBytes() { N := int(1e6) src := bytes.Repeat([]byte{'1'}, N) t.Nil(t.enc.Encode(src)) var dst []byte t.Nil(t.dec.Decode(&dst)) t.Equal(dst, src) } func (t *MsgpackTest) TestLargeString() { N := int(1e6) src := string(bytes.Repeat([]byte{'1'}, N)) t.Nil(t.enc.Encode(src)) var dst string t.Nil(t.dec.Decode(&dst)) t.Equal(dst, src) } func (t *MsgpackTest) TestSliceOfStructs() { in := []*nameStruct{{"hello"}} var out []*nameStruct t.Nil(t.enc.Encode(in)) t.Nil(t.dec.Decode(&out)) t.Equal(out, in) } func (t *MsgpackTest) TestMap() { 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}}, } { t.Nil(t.enc.Encode(i.m)) t.Equal(t.buf.Bytes(), i.b, fmt.Errorf("err encoding %v", i.m)) var m map[string]string t.Nil(t.dec.Decode(&m)) t.Equal(m, i.m) } } func (t *MsgpackTest) TestStructNil() { var dst *nameStruct t.Nil(t.enc.Encode(nameStruct{Name: "foo"})) t.Nil(t.dec.Decode(&dst)) t.NotNil(dst) t.Equal(dst.Name, "foo") } func (t *MsgpackTest) TestStructUnknownField() { in := struct { Field1 string Field2 string Field3 string }{ Field1: "value1", Field2: "value2", Field3: "value3", } t.Nil(t.enc.Encode(in)) out := struct { Field2 string }{} t.Nil(t.dec.Decode(&out)) t.Equal(out.Field2, "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() { in := &coderStruct{name: "hello"} var out coderStruct t.Nil(t.enc.Encode(in)) t.Nil(t.dec.Decode(&out)) t.Equal(out.Name(), "hello") } func (t *MsgpackTest) TestNilCoder() { in := &coderStruct{name: "hello"} var out *coderStruct t.Nil(t.enc.Encode(in)) t.Nil(t.dec.Decode(&out)) t.Equal(out.Name(), "hello") } func (t *MsgpackTest) TestNilCoderValue() { in := &coderStruct{name: "hello"} var out *coderStruct t.Nil(t.enc.Encode(in)) t.Nil(t.dec.DecodeValue(reflect.ValueOf(&out))) t.Equal(out.Name(), "hello") } func (t *MsgpackTest) TestPtrToCoder() { in := &coderStruct{name: "hello"} var out coderStruct out2 := &out t.Nil(t.enc.Encode(in)) t.Nil(t.dec.Decode(&out2)) t.Equal(out.Name(), "hello") } func (t *MsgpackTest) TestWrappedCoder() { in := &wrapperStruct{coderStruct: coderStruct{name: "hello"}} var out wrapperStruct t.Nil(t.enc.Encode(in)) t.Nil(t.dec.Decode(&out)) t.Equal(out.Name(), "hello") } //------------------------------------------------------------------------------ type struct2 struct { Name string } type struct1 struct { Name string Struct2 struct2 } func (t *MsgpackTest) TestNestedStructs() { in := &struct1{Name: "hello", Struct2: struct2{Name: "world"}} var out struct1 t.Nil(t.enc.Encode(in)) t.Nil(t.dec.Decode(&out)) t.Equal(out.Name, in.Name) t.Equal(out.Struct2.Name, 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() { in := [][]*int{nil} var out [][]*int t.Nil(t.enc.Encode(in)) t.Nil(t.dec.Decode(&out)) t.Equal(out, in) } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ func TestNoPanicOnUnsupportedKey(t *testing.T) { data := []byte{0x81, 0x81, 0xa1, 0x78, 0xc3, 0xc3} _, err := msgpack.NewDecoder(bytes.NewReader(data)).DecodeTypedMap() require.EqualError(t, err, "msgpack: unsupported map key: map[string]interface {}") } func TestMapDefault(t *testing.T) { in := map[string]interface{}{ "foo": "bar", "hello": map[string]interface{}{ "foo": "bar", }, } b, err := msgpack.Marshal(in) require.Nil(t, err) var out map[string]interface{} err = msgpack.Unmarshal(b, &out) require.Nil(t, err) require.Equal(t, in, out) } func TestRawMessage(t *testing.T) { type In struct { Foo map[string]interface{} } type Out struct { Foo msgpack.RawMessage } type Out2 struct { Foo interface{} } b, err := msgpack.Marshal(&In{ Foo: map[string]interface{}{ "hello": "world", }, }) require.Nil(t, err) var out Out err = msgpack.Unmarshal(b, &out) require.Nil(t, err) var m map[string]string err = msgpack.Unmarshal(out.Foo, &m) require.Nil(t, err) require.Equal(t, map[string]string{ "hello": "world", }, m) msg := new(msgpack.RawMessage) out2 := Out2{ Foo: msg, } err = msgpack.Unmarshal(b, &out2) require.Nil(t, err) require.Equal(t, out.Foo, *msg) } func TestInterface(t *testing.T) { type Interface struct { Foo interface{} } in := Interface{Foo: "foo"} b, err := msgpack.Marshal(in) require.Nil(t, err) var str string out := Interface{Foo: &str} err = msgpack.Unmarshal(b, &out) require.Nil(t, err) require.Equal(t, "foo", str) } func TestNaN(t *testing.T) { in := float64(math.NaN()) b, err := msgpack.Marshal(in) require.Nil(t, err) var out float64 err = msgpack.Unmarshal(b, &out) require.Nil(t, err) require.True(t, math.IsNaN(out)) } func TestSetSortMapKeys(t *testing.T) { in := map[string]interface{}{ "a": "a", "b": "b", "c": "c", "d": "d", } var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) enc.SetSortMapKeys(true) dec := msgpack.NewDecoder(&buf) err := enc.Encode(in) require.Nil(t, err) wanted := make([]byte, buf.Len()) copy(wanted, buf.Bytes()) buf.Reset() for i := 0; i < 100; i++ { err := enc.Encode(in) require.Nil(t, err) require.Equal(t, wanted, buf.Bytes()) out, err := dec.DecodeMap() require.Nil(t, err) require.Equal(t, in, out) } } func TestSetOmitEmpty(t *testing.T) { var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) enc.SetOmitEmpty(true) err := enc.Encode(EmbeddingPtrTest{}) require.Nil(t, err) var t2 *EmbeddingPtrTest dec := msgpack.NewDecoder(&buf) err = dec.Decode(&t2) require.Nil(t, err) require.Nil(t, t2.Exported) } type NullInt struct { Valid bool Int int } func (i *NullInt) Set(j int) { i.Int = j i.Valid = true } func (i NullInt) IsZero() bool { return !i.Valid } func (i NullInt) MarshalMsgpack() ([]byte, error) { return msgpack.Marshal(i.Int) } func (i *NullInt) UnmarshalMsgpack(b []byte) error { if err := msgpack.Unmarshal(b, &i.Int); err != nil { return err } i.Valid = true return nil } type Secretive struct { Visible bool hidden bool } type T struct { I NullInt `msgpack:",omitempty"` J NullInt // Secretive is not a "simple" struct because it has an hidden field. S Secretive `msgpack:",omitempty"` } func ExampleMarshal_ignore_simple_zero_structs_when_tagged_with_omitempty() { var t1 T raw, err := msgpack.Marshal(t1) if err != nil { panic(err) } var t2 T if err = msgpack.Unmarshal(raw, &t2); err != nil { panic(err) } fmt.Printf("%#v\n", t2) t2.I.Set(42) t2.S.hidden = true // won't be included because it is a hidden field raw, err = msgpack.Marshal(t2) if err != nil { panic(err) } var t3 T if err = msgpack.Unmarshal(raw, &t3); err != nil { panic(err) } fmt.Printf("%#v\n", t3) // Output: msgpack_test.T{I:msgpack_test.NullInt{Valid:false, Int:0}, J:msgpack_test.NullInt{Valid:true, Int:0}, S:msgpack_test.Secretive{Visible:false, hidden:false}} // msgpack_test.T{I:msgpack_test.NullInt{Valid:true, Int:42}, J:msgpack_test.NullInt{Valid:true, Int:0}, S:msgpack_test.Secretive{Visible:false, hidden:false}} } type Value interface{} type Wrapper struct { Value Value `msgpack:"v,omitempty"` } func TestEncodeWrappedValue(t *testing.T) { var v Value v = (*time.Time)(nil) c := &Wrapper{ Value: v, } var buf bytes.Buffer require.Nil(t, msgpack.NewEncoder(&buf).Encode(v)) require.Nil(t, msgpack.NewEncoder(&buf).Encode(c)) } msgpack-5.3.5/msgpcode/000077500000000000000000000000001413451025300147505ustar00rootroot00000000000000msgpack-5.3.5/msgpcode/msgpcode.go000066400000000000000000000032121413451025300170760ustar00rootroot00000000000000package msgpcode var ( PosFixedNumHigh byte = 0x7f NegFixedNumLow byte = 0xe0 Nil byte = 0xc0 False byte = 0xc2 True byte = 0xc3 Float byte = 0xca Double byte = 0xcb Uint8 byte = 0xcc Uint16 byte = 0xcd Uint32 byte = 0xce Uint64 byte = 0xcf Int8 byte = 0xd0 Int16 byte = 0xd1 Int32 byte = 0xd2 Int64 byte = 0xd3 FixedStrLow byte = 0xa0 FixedStrHigh byte = 0xbf FixedStrMask byte = 0x1f Str8 byte = 0xd9 Str16 byte = 0xda Str32 byte = 0xdb Bin8 byte = 0xc4 Bin16 byte = 0xc5 Bin32 byte = 0xc6 FixedArrayLow byte = 0x90 FixedArrayHigh byte = 0x9f FixedArrayMask byte = 0xf Array16 byte = 0xdc Array32 byte = 0xdd FixedMapLow byte = 0x80 FixedMapHigh byte = 0x8f FixedMapMask byte = 0xf Map16 byte = 0xde Map32 byte = 0xdf FixExt1 byte = 0xd4 FixExt2 byte = 0xd5 FixExt4 byte = 0xd6 FixExt8 byte = 0xd7 FixExt16 byte = 0xd8 Ext8 byte = 0xc7 Ext16 byte = 0xc8 Ext32 byte = 0xc9 ) func IsFixedNum(c byte) bool { return c <= PosFixedNumHigh || c >= NegFixedNumLow } func IsFixedMap(c byte) bool { return c >= FixedMapLow && c <= FixedMapHigh } func IsFixedArray(c byte) bool { return c >= FixedArrayLow && c <= FixedArrayHigh } func IsFixedString(c byte) bool { return c >= FixedStrLow && c <= FixedStrHigh } func IsString(c byte) bool { return IsFixedString(c) || c == Str8 || c == Str16 || c == Str32 } func IsBin(c byte) bool { return c == Bin8 || c == Bin16 || c == Bin32 } func IsFixedExt(c byte) bool { return c >= FixExt1 && c <= FixExt16 } func IsExt(c byte) bool { return IsFixedExt(c) || c == Ext8 || c == Ext16 || c == Ext32 } msgpack-5.3.5/package.json000066400000000000000000000000561413451025300154360ustar00rootroot00000000000000{ "name": "msgpack", "version": "5.3.5" } msgpack-5.3.5/safe.go000066400000000000000000000003731413451025300144170ustar00rootroot00000000000000// +build appengine package msgpack // bytesToString converts byte slice to string. func bytesToString(b []byte) string { return string(b) } // stringToBytes converts string to byte slice. func stringToBytes(s string) []byte { return []byte(s) } msgpack-5.3.5/time.go000066400000000000000000000055061413451025300144420ustar00rootroot00000000000000package msgpack import ( "encoding/binary" "fmt" "reflect" "time" "github.com/vmihailenco/msgpack/v5/msgpcode" ) var timeExtID int8 = -1 func init() { RegisterExtEncoder(timeExtID, time.Time{}, timeEncoder) RegisterExtDecoder(timeExtID, time.Time{}, timeDecoder) } func timeEncoder(e *Encoder, v reflect.Value) ([]byte, error) { return e.encodeTime(v.Interface().(time.Time)), nil } func timeDecoder(d *Decoder, v reflect.Value, extLen int) error { tm, err := d.decodeTime(extLen) if err != nil { return err } ptr := v.Addr().Interface().(*time.Time) *ptr = tm return nil } 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 { if e.timeBuf == nil { e.timeBuf = make([]byte, 12) } secs := uint64(tm.Unix()) if secs>>34 == 0 { data := uint64(tm.Nanosecond())<<34 | secs if data&0xffffffff00000000 == 0 { b := e.timeBuf[:4] binary.BigEndian.PutUint32(b, uint32(data)) return b } b := e.timeBuf[:8] binary.BigEndian.PutUint64(b, data) return b } b := e.timeBuf[:12] binary.BigEndian.PutUint32(b, uint32(tm.Nanosecond())) binary.BigEndian.PutUint64(b[4:], 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 == msgpcode.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 } if msgpcode.IsString(c) { s, err := d.string(c) if err != nil { return time.Time{}, err } return time.Parse(time.RFC3339Nano, s) } extID, extLen, err := d.extHeader(c) if err != nil { return time.Time{}, err } if extID != timeExtID { return time.Time{}, fmt.Errorf("msgpack: invalid time ext id=%d", extID) } tm, err := d.decodeTime(extLen) if err != nil { return tm, err } if tm.IsZero() { // Zero time does not have timezone information. return tm.UTC(), nil } return tm, nil } func (d *Decoder) decodeTime(extLen int) (time.Time, error) { 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: err = fmt.Errorf("msgpack: invalid ext len=%d decoding time", extLen) return time.Time{}, err } } msgpack-5.3.5/types.go000066400000000000000000000205771413451025300146550ustar00rootroot00000000000000package msgpack import ( "encoding" "fmt" "log" "reflect" "sync" "github.com/vmihailenco/tagparser/v2" ) var errorType = reflect.TypeOf((*error)(nil)).Elem() var ( customEncoderType = reflect.TypeOf((*CustomEncoder)(nil)).Elem() customDecoderType = reflect.TypeOf((*CustomDecoder)(nil)).Elem() ) var ( marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() ) var ( binaryMarshalerType = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem() binaryUnmarshalerType = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem() ) var ( textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() ) type ( encoderFunc func(*Encoder, reflect.Value) error decoderFunc func(*Decoder, reflect.Value) error ) var ( typeEncMap sync.Map typeDecMap sync.Map ) // Register registers encoder and decoder functions for a value. // This is low level API and in most cases you should prefer implementing // CustomEncoder/CustomDecoder or Marshaler/Unmarshaler interfaces. func Register(value interface{}, enc encoderFunc, dec decoderFunc) { typ := reflect.TypeOf(value) if enc != nil { typeEncMap.Store(typ, enc) } if dec != nil { typeDecMap.Store(typ, dec) } } //------------------------------------------------------------------------------ const defaultStructTag = "msgpack" var structs = newStructCache() type structCache struct { m sync.Map } type structCacheKey struct { tag string typ reflect.Type } func newStructCache() *structCache { return new(structCache) } func (m *structCache) Fields(typ reflect.Type, tag string) *fields { key := structCacheKey{tag: tag, typ: typ} if v, ok := m.m.Load(key); ok { return v.(*fields) } fs := getFields(typ, tag) m.m.Store(key, fs) return fs } //------------------------------------------------------------------------------ type field struct { name string index []int omitEmpty bool encoder encoderFunc decoder decoderFunc } func (f *field) Omit(strct reflect.Value, forced bool) bool { v, ok := fieldByIndex(strct, f.index) if !ok { return true } return (f.omitEmpty || forced) && isEmptyValue(v) } func (f *field) EncodeValue(e *Encoder, strct reflect.Value) error { v, ok := fieldByIndex(strct, f.index) if !ok { return e.EncodeNil() } return f.encoder(e, v) } func (f *field) DecodeValue(d *Decoder, strct reflect.Value) error { v := fieldByIndexAlloc(strct, f.index) return f.decoder(d, v) } //------------------------------------------------------------------------------ type fields struct { Type reflect.Type Map map[string]*field List []*field AsArray bool hasOmitEmpty bool } func newFields(typ reflect.Type) *fields { return &fields{ Type: typ, Map: make(map[string]*field, typ.NumField()), List: make([]*field, 0, typ.NumField()), } } func (fs *fields) Add(field *field) { fs.warnIfFieldExists(field.name) fs.Map[field.name] = field fs.List = append(fs.List, field) if field.omitEmpty { fs.hasOmitEmpty = true } } func (fs *fields) warnIfFieldExists(name string) { if _, ok := fs.Map[name]; ok { log.Printf("msgpack: %s already has field=%s", fs.Type, name) } } func (fs *fields) OmitEmpty(strct reflect.Value, forced bool) []*field { if !fs.hasOmitEmpty && !forced { return fs.List } fields := make([]*field, 0, len(fs.List)) for _, f := range fs.List { if !f.Omit(strct, forced) { fields = append(fields, f) } } return fields } func getFields(typ reflect.Type, fallbackTag string) *fields { fs := newFields(typ) var omitEmpty bool for i := 0; i < typ.NumField(); i++ { f := typ.Field(i) tagStr := f.Tag.Get(defaultStructTag) if tagStr == "" && fallbackTag != "" { tagStr = f.Tag.Get(fallbackTag) } tag := tagparser.Parse(tagStr) if tag.Name == "-" { continue } if f.Name == "_msgpack" { fs.AsArray = tag.HasOption("as_array") || tag.HasOption("asArray") if tag.HasOption("omitempty") { omitEmpty = true } } if f.PkgPath != "" && !f.Anonymous { continue } field := &field{ name: tag.Name, index: f.Index, omitEmpty: omitEmpty || tag.HasOption("omitempty"), } if tag.HasOption("intern") { switch f.Type.Kind() { case reflect.Interface: field.encoder = encodeInternedInterfaceValue field.decoder = decodeInternedInterfaceValue case reflect.String: field.encoder = encodeInternedStringValue field.decoder = decodeInternedStringValue default: err := fmt.Errorf("msgpack: intern strings are not supported on %s", f.Type) panic(err) } } else { field.encoder = getEncoder(f.Type) field.decoder = getDecoder(f.Type) } if field.name == "" { field.name = f.Name } if f.Anonymous && !tag.HasOption("noinline") { inline := tag.HasOption("inline") if inline { inlineFields(fs, f.Type, field, fallbackTag) } else { inline = shouldInline(fs, f.Type, field, fallbackTag) } if inline { if _, ok := fs.Map[field.name]; ok { log.Printf("msgpack: %s already has field=%s", fs.Type, field.name) } fs.Map[field.name] = field continue } } fs.Add(field) if alias, ok := tag.Options["alias"]; ok { fs.warnIfFieldExists(alias) fs.Map[alias] = field } } return fs } var ( encodeStructValuePtr uintptr decodeStructValuePtr uintptr ) //nolint:gochecknoinits func init() { encodeStructValuePtr = reflect.ValueOf(encodeStructValue).Pointer() decodeStructValuePtr = reflect.ValueOf(decodeStructValue).Pointer() } func inlineFields(fs *fields, typ reflect.Type, f *field, tag string) { inlinedFields := getFields(typ, tag).List for _, field := range inlinedFields { if _, ok := fs.Map[field.name]; ok { // Don't inline shadowed fields. continue } field.index = append(f.index, field.index...) fs.Add(field) } } func shouldInline(fs *fields, typ reflect.Type, f *field, tag string) 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, tag).List for _, field := range inlinedFields { if _, ok := fs.Map[field.name]; ok { // Don't auto inline if there are shadowed fields. return false } } for _, field := range inlinedFields { field.index = append(f.index, field.index...) fs.Add(field) } return true } type isZeroer interface { IsZero() bool } func isEmptyValue(v reflect.Value) bool { kind := v.Kind() for kind == reflect.Interface { if v.IsNil() { return true } v = v.Elem() kind = v.Kind() } if z, ok := v.Interface().(isZeroer); ok { return nilable(kind) && v.IsNil() || z.IsZero() } switch 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.Ptr: return v.IsNil() default: return false } } func fieldByIndex(v reflect.Value, index []int) (_ reflect.Value, ok bool) { if len(index) == 1 { return v.Field(index[0]), true } for i, idx := range index { if i > 0 { if v.Kind() == reflect.Ptr { if v.IsNil() { return v, false } v = v.Elem() } } v = v.Field(idx) } return v, true } func fieldByIndexAlloc(v reflect.Value, index []int) reflect.Value { if len(index) == 1 { return v.Field(index[0]) } for i, idx := range index { if i > 0 { var ok bool v, ok = indirectNil(v) if !ok { return v } } v = v.Field(idx) } return v } func indirectNil(v reflect.Value) (reflect.Value, bool) { if v.Kind() == reflect.Ptr { if v.IsNil() { if !v.CanSet() { return v, false } elemType := v.Type().Elem() if elemType.Kind() != reflect.Struct { return v, false } v.Set(reflect.New(elemType)) } v = v.Elem() } return v, true } msgpack-5.3.5/types_test.go000066400000000000000000000654301413451025300157110ustar00rootroot00000000000000package msgpack_test import ( "bytes" "encoding/hex" "fmt" "math" "math/big" "net/url" "reflect" "strings" "testing" "time" "github.com/stretchr/testify/require" "github.com/vmihailenco/msgpack/v5" "github.com/vmihailenco/msgpack/v5/msgpcode" ) //------------------------------------------------------------------------------ type Object struct { n int64 } 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 CustomTime time.Time func (t CustomTime) EncodeMsgpack(enc *msgpack.Encoder) error { return enc.Encode(time.Time(t)) } func (t *CustomTime) DecodeMsgpack(dec *msgpack.Decoder) error { var tm time.Time err := dec.Decode(&tm) if err != nil { return err } *t = CustomTime(tm) return nil } //------------------------------------------------------------------------------ type IntSet map[int]struct{} var ( _ msgpack.CustomEncoder = (*IntSet)(nil) _ 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) _ msgpack.CustomDecoder = (*CustomEncoder)(nil) ) func (s *CustomEncoder) EncodeMsgpack(enc *msgpack.Encoder) error { if s == nil { return enc.EncodeNil() } return enc.EncodeMulti(s.str, s.ref, s.num) } func (s *CustomEncoder) DecodeMsgpack(dec *msgpack.Decoder) error { return dec.DecodeMulti(&s.str, &s.ref, &s.num) } type CustomEncoderField struct { Field CustomEncoder } type CustomEncoderEmbeddedPtr struct { *CustomEncoder } func (s *CustomEncoderEmbeddedPtr) DecodeMsgpack(dec *msgpack.Decoder) error { if s.CustomEncoder == nil { s.CustomEncoder = new(CustomEncoder) } return s.CustomEncoder.DecodeMsgpack(dec) } //------------------------------------------------------------------------------ type JSONFallbackTest struct { Foo string `json:"foo,omitempty"` Bar string `json:",omitempty" msgpack:"bar"` } func TestUseJsonTag(t *testing.T) { var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) enc.SetCustomStructTag("json") in := &JSONFallbackTest{Foo: "hello", Bar: "world"} err := enc.Encode(in) if err != nil { t.Fatal(err) } dec := msgpack.NewDecoder(&buf) dec.SetCustomStructTag("json") out := new(JSONFallbackTest) err = dec.Decode(out) if err != nil { t.Fatal(err) } if out.Foo != in.Foo { t.Fatalf("got %q, wanted %q", out.Foo, in.Foo) } if out.Bar != in.Bar { t.Fatalf("got %q, wanted %q", out.Foo, in.Foo) } } //------------------------------------------------------------------------------ type CustomFallbackTest struct { Foo string `custom:"foo,omitempty"` Bar string `custom:",omitempty" msgpack:"bar"` } func TestUseCustomTag(t *testing.T) { var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) enc.SetCustomStructTag("custom") in := &CustomFallbackTest{Foo: "hello", Bar: "world"} err := enc.Encode(in) if err != nil { t.Fatal(err) } dec := msgpack.NewDecoder(&buf) dec.SetCustomStructTag("custom") out := new(CustomFallbackTest) err = dec.Decode(out) if err != nil { t.Fatal(err) } if out.Foo != in.Foo || out.Foo != "hello" { t.Fatalf("got %q, wanted %q", out.Foo, in.Foo) } if out.Bar != in.Bar || out.Bar != "world" { t.Fatalf("got %q, wanted %q", out.Foo, in.Foo) } } //------------------------------------------------------------------------------ type OmitTimeTest struct { Foo time.Time `msgpack:",omitempty"` Bar *time.Time `msgpack:",omitempty"` } type OmitEmptyTest struct { Foo string `msgpack:",omitempty"` Bar string `msgpack:",omitempty"` } type InlineTest struct { OmitEmptyTest } type InlinePtrTest struct { *OmitEmptyTest } type FooTest struct { Foo string } type FooDupTest FooTest type InlineDupTest struct { FooTest FooDupTest } type AsArrayTest struct { _msgpack struct{} `msgpack:",as_array"` OmitEmptyTest } type ExtTestField struct { ExtTest ExtTest } //------------------------------------------------------------------------------ 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{}, "d30000000000000000"}, {&Object{42}, "d3000000000000002a"}, {[]*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"}, {&JSONFallbackTest{Foo: "hello"}, "82a3666f6fa568656c6c6fa3626172a0"}, {&JSONFallbackTest{Bar: "world"}, "81a3626172a5776f726c64"}, {&JSONFallbackTest{Foo: "hello", Bar: "world"}, "82a3666f6fa568656c6c6fa3626172a5776f726c64"}, {&NoIntern{A: "foo", B: "foo", C: "foo"}, "83a141a3666f6fa142a3666f6fa143a3666f6f"}, {&Intern{A: "foo", B: "foo", C: "foo"}, "83a141a3666f6fa142d48000a143d48000"}, } func TestEncoder(t *testing.T) { var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) enc.SetCustomStructTag("json") enc.SetSortMapKeys(true) enc.UseCompactInts(true) for i, test := range encoderTests { buf.Reset() err := enc.Encode(test.in) require.Nil(t, err) s := hex.EncodeToString(buf.Bytes()) require.Equal(t, test.wanted, s, "#%d", i) } } type floatEncoderTest struct { in interface{} wanted string compact bool } var floatEncoderTests = []floatEncoderTest{ {float32(3.0), "ca40400000", false}, {float32(3.0), "03", true}, {float64(3.0), "cb4008000000000000", false}, {float64(3.0), "03", true}, {float64(-3.0), "cbc008000000000000", false}, {float64(-3.0), "fd", true}, {math.NaN(), "cb7ff8000000000001", false}, {math.NaN(), "cb7ff8000000000001", true}, {math.Inf(1), "cb7ff0000000000000", false}, {math.Inf(1), "cb7ff0000000000000", true}, } func TestFloatEncoding(t *testing.T) { var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) enc.UseCompactInts(true) for _, test := range floatEncoderTests { buf.Reset() enc.UseCompactFloats(test.compact) err := enc.Encode(test.in) if 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(msgpcode.Bin32), 0x0f, 0xff, 0xff, 0xff}, out: new([]byte), err: "EOF"}, {b: []byte{byte(msgpcode.Str32), 0x0f, 0xff, 0xff, 0xff}, out: new([]byte), err: "EOF"}, {b: []byte{byte(msgpcode.Array32), 0x0f, 0xff, 0xff, 0xff}, out: new([]int), err: "EOF"}, {b: []byte{byte(msgpcode.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 EmbeddingTest struct { unexported Exported } type EmbeddingPtrTest struct { *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) requireErr(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(non-pointer int)"}, {in: nil, out: (*int)(nil), decErr: "msgpack: Decode(non-settable *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]string(nil), out: new(map[string]string)}, {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: map[int]string{1: "string"}, out: new(map[int]string)}, {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: EmbeddingTest{}, out: new(EmbeddingTest)}, { in: EmbeddingTest{}, out: new(EmbeddingPtrTest), wanted: EmbeddingPtrTest{Exported: new(Exported)}, }, { in: EmbeddingPtrTest{}, out: new(EmbeddingPtrTest), wanted: EmbeddingPtrTest{Exported: new(Exported)}, }, {in: EmbeddingTest{}, out: new(*EmbeddingTest)}, { in: EmbeddingTest{ unexported: unexported{Foo: "hello"}, Exported: Exported{Bar: "world"}, }, out: new(EmbeddingTest), }, {in: time.Unix(0, 0), out: new(time.Time)}, {in: new(time.Time), 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: time.Unix(0, 0).Format(time.RFC3339), out: new(time.Time), wanted: mustParseTime(time.RFC3339, time.Unix(0, 0).Format(time.RFC3339)), }, {in: EmbeddedTime{Time: time.Unix(1, 1)}, out: new(EmbeddedTime)}, {in: EmbeddedTime{Time: time.Unix(1, 1)}, out: new(*EmbeddedTime)}, {in: CustomTime(time.Unix(0, 0)), out: new(CustomTime)}, {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: &CustomEncoderEmbeddedPtr{&CustomEncoder{"a", nil, 1}}, out: new(CustomEncoderEmbeddedPtr), }, {in: repoURL, out: new(url.URL)}, {in: repoURL, out: new(*url.URL)}, {in: OmitEmptyTest{}, out: new(OmitEmptyTest)}, {in: OmitTimeTest{}, out: new(OmitTimeTest)}, {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), decErr: "msgpack: number of fields in array-encoded struct has changed", }, {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"}}, { in: &ExtTestField{ExtTest{"world"}}, out: new(*ExtTestField), wanted: ExtTestField{ExtTest{"hello world"}}, }, { in: &InlineTest{OmitEmptyTest: OmitEmptyTest{Bar: "world"}}, out: new(InlineTest), }, { in: &InlinePtrTest{OmitEmptyTest: &OmitEmptyTest{Bar: "world"}}, out: new(InlinePtrTest), }, { in: InlineDupTest{FooTest{"foo"}, FooDupTest{"foo"}}, out: new(InlineDupTest), }, {in: big.NewInt(123), out: new(big.Int)}, } ) 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) { msgpack.RegisterExt(1, (*EventTime)(nil)) for _, test := range typeTests { test.T = t var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) err := enc.Encode(test.in) if test.encErr != "" { test.requireErr(err, test.encErr) continue } if err != nil { t.Fatalf("Encode failed: %s (in=%#v)", err, test.in) } dec := msgpack.NewDecoder(&buf) err = dec.Decode(test.out) if test.decErr != "" { test.requireErr(err, test.decErr) continue } if err != nil { t.Fatalf("Decode 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) } require.Equal(t, wanted, out) } for _, test := range typeTests { if test.encErr != "" || test.decErr != "" { continue } b, err := msgpack.Marshal(test.in) if err != nil { t.Fatal(err) } var dst interface{} dec := msgpack.NewDecoder(bytes.NewReader(b)) dec.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) { return dec.DecodeUntypedMap() }) err = dec.Decode(&dst) if err != nil { t.Fatalf("Unmarshal into interface{} failed: %s (%s)", err, test) } dec = msgpack.NewDecoder(bytes.NewReader(b)) dec.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) { return dec.DecodeUntypedMap() }) _, err = dec.DecodeInterface() if err != nil { t.Fatalf("DecodeInterface failed: %s (%s)", err, test) } } } func TestStringsBin(t *testing.T) { tests := []struct { in string wanted string }{ {"", "a0"}, {"a", "a161"}, {"hello", "a568656c6c6f"}, { strings.Repeat("x", 31), "bf" + strings.Repeat("78", 31), }, { strings.Repeat("x", 32), "d920" + strings.Repeat("78", 32), }, { strings.Repeat("x", 255), "d9ff" + strings.Repeat("78", 255), }, { strings.Repeat("x", 256), "da0100" + strings.Repeat("78", 256), }, { strings.Repeat("x", 65535), "daffff" + strings.Repeat("78", 65535), }, { strings.Repeat("x", 65536), "db00010000" + strings.Repeat("78", 65536), }, } for _, test := range tests { b, err := msgpack.Marshal(test.in) require.Nil(t, err) s := hex.EncodeToString(b) require.Equal(t, s, test.wanted) var out string err = msgpack.Unmarshal(b, &out) require.Nil(t, err) require.Equal(t, out, test.in) var msg msgpack.RawMessage err = msgpack.Unmarshal(b, &msg) require.Nil(t, err) require.Equal(t, []byte(msg), b) dec := msgpack.NewDecoder(bytes.NewReader(b)) v, err := dec.DecodeInterface() require.Nil(t, err) require.Equal(t, v.(string), test.in) var dst interface{} dst = "" err = msgpack.Unmarshal(b, &dst) require.EqualError(t, err, "msgpack: Decode(non-pointer string)") } } func TestBin(t *testing.T) { tests := []struct { in []byte wanted string }{ {[]byte{}, "c400"}, {[]byte{0}, "c40100"}, { bytes.Repeat([]byte{'x'}, 31), "c41f" + strings.Repeat("78", 31), }, { bytes.Repeat([]byte{'x'}, 32), "c420" + strings.Repeat("78", 32), }, { bytes.Repeat([]byte{'x'}, 255), "c4ff" + strings.Repeat("78", 255), }, { bytes.Repeat([]byte{'x'}, 256), "c50100" + strings.Repeat("78", 256), }, { bytes.Repeat([]byte{'x'}, 65535), "c5ffff" + strings.Repeat("78", 65535), }, { bytes.Repeat([]byte{'x'}, 65536), "c600010000" + strings.Repeat("78", 65536), }, } for _, test := range tests { b, err := msgpack.Marshal(test.in) if err != nil { t.Fatal(err) } s := hex.EncodeToString(b) if s != test.wanted { t.Fatalf("%.32s != %.32s", s, test.wanted) } var out []byte err = msgpack.Unmarshal(b, &out) if err != nil { t.Fatal(err) } if !bytes.Equal(out, test.in) { t.Fatalf("%x != %x", out, test.in) } dec := msgpack.NewDecoder(bytes.NewReader(b)) v, err := dec.DecodeInterface() if err != nil { t.Fatal(err) } if !bytes.Equal(v.([]byte), test.in) { t.Fatalf("%x != %x", v, test.in) } var dst interface{} dst = make([]byte, 0) err = msgpack.Unmarshal(b, &dst) if err.Error() != "msgpack: Decode(non-pointer []uint8)" { t.Fatal(err) } } } func TestUint64(t *testing.T) { tests := []struct { in uint64 wanted string }{ {0, "00"}, {1, "01"}, {math.MaxInt8 - 1, "7e"}, {math.MaxInt8, "7f"}, {math.MaxInt8 + 1, "cc80"}, {math.MaxUint8 - 1, "ccfe"}, {math.MaxUint8, "ccff"}, {math.MaxUint8 + 1, "cd0100"}, {math.MaxUint16 - 1, "cdfffe"}, {math.MaxUint16, "cdffff"}, {math.MaxUint16 + 1, "ce00010000"}, {math.MaxUint32 - 1, "cefffffffe"}, {math.MaxUint32, "ceffffffff"}, {math.MaxUint32 + 1, "cf0000000100000000"}, {math.MaxInt64 - 1, "cf7ffffffffffffffe"}, {math.MaxInt64, "cf7fffffffffffffff"}, } var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) enc.UseCompactInts(true) for _, test := range tests { err := enc.Encode(test.in) if err != nil { t.Fatal(err) } s := hex.EncodeToString(buf.Bytes()) if s != test.wanted { t.Fatalf("%.32s != %.32s", s, test.wanted) } var out uint64 err = msgpack.Unmarshal(buf.Bytes(), &out) if err != nil { t.Fatal(err) } if out != test.in { t.Fatalf("%d != %d", out, test.in) } var out2 int64 err = msgpack.Unmarshal(buf.Bytes(), &out2) if err != nil { t.Fatal(err) } if out2 != int64(test.in) { t.Fatalf("%d != %d", out2, int64(test.in)) } var out3 interface{} out3 = uint64(0) err = msgpack.Unmarshal(buf.Bytes(), &out3) if err.Error() != "msgpack: Decode(non-pointer uint64)" { t.Fatal(err) } dec := msgpack.NewDecoder(&buf) _, err = dec.DecodeInterface() if err != nil { t.Fatal(err) } if buf.Len() != 0 { panic("buffer is not empty") } } } func TestInt64(t *testing.T) { tests := []struct { in int64 wanted string }{ {math.MinInt64, "d38000000000000000"}, {math.MinInt32 - 1, "d3ffffffff7fffffff"}, {math.MinInt32, "d280000000"}, {math.MinInt32 + 1, "d280000001"}, {math.MinInt16 - 1, "d2ffff7fff"}, {math.MinInt16, "d18000"}, {math.MinInt16 + 1, "d18001"}, {math.MinInt8 - 1, "d1ff7f"}, {math.MinInt8, "d080"}, {math.MinInt8 + 1, "d081"}, {-33, "d0df"}, {-32, "e0"}, {-31, "e1"}, {-1, "ff"}, {0, "00"}, {1, "01"}, {math.MaxInt8 - 1, "7e"}, {math.MaxInt8, "7f"}, {math.MaxInt8 + 1, "cc80"}, {math.MaxUint8 - 1, "ccfe"}, {math.MaxUint8, "ccff"}, {math.MaxUint8 + 1, "cd0100"}, {math.MaxUint16 - 1, "cdfffe"}, {math.MaxUint16, "cdffff"}, {math.MaxUint16 + 1, "ce00010000"}, {math.MaxUint32 - 1, "cefffffffe"}, {math.MaxUint32, "ceffffffff"}, {math.MaxUint32 + 1, "cf0000000100000000"}, {math.MaxInt64 - 1, "cf7ffffffffffffffe"}, {math.MaxInt64, "cf7fffffffffffffff"}, } var buf bytes.Buffer enc := msgpack.NewEncoder(&buf) enc.UseCompactInts(true) for _, test := range tests { err := enc.Encode(test.in) if err != nil { t.Fatal(err) } s := hex.EncodeToString(buf.Bytes()) if s != test.wanted { t.Fatalf("%.32s != %.32s", s, test.wanted) } var out int64 err = msgpack.Unmarshal(buf.Bytes(), &out) if err != nil { t.Fatal(err) } if out != test.in { t.Fatalf("%d != %d", out, test.in) } var out2 uint64 err = msgpack.Unmarshal(buf.Bytes(), &out2) if err != nil { t.Fatal(err) } if out2 != uint64(test.in) { t.Fatalf("%d != %d", out2, uint64(test.in)) } var out3 interface{} out3 = int64(0) err = msgpack.Unmarshal(buf.Bytes(), &out3) if err.Error() != "msgpack: Decode(non-pointer int64)" { t.Fatal(err) } dec := msgpack.NewDecoder(&buf) _, err = dec.DecodeInterface() if err != nil { t.Fatal(err) } if buf.Len() != 0 { panic("buffer is not empty") } } } func TestFloat32(t *testing.T) { tests := []struct { in float32 wanted string }{ {0.1, "ca3dcccccd"}, {0.2, "ca3e4ccccd"}, {-0.1, "cabdcccccd"}, {-0.2, "cabe4ccccd"}, {float32(math.Inf(1)), "ca7f800000"}, {float32(math.Inf(-1)), "caff800000"}, {math.MaxFloat32, "ca7f7fffff"}, {math.SmallestNonzeroFloat32, "ca00000001"}, } for _, test := range tests { b, err := msgpack.Marshal(test.in) if err != nil { t.Fatal(err) } s := hex.EncodeToString(b) if s != test.wanted { t.Fatalf("%.32s != %.32s", s, test.wanted) } var out float32 err = msgpack.Unmarshal(b, &out) if err != nil { t.Fatal(err) } if out != test.in { t.Fatalf("%f != %f", out, test.in) } var out2 float64 err = msgpack.Unmarshal(b, &out2) if err != nil { t.Fatal(err) } if out2 != float64(test.in) { t.Fatalf("%f != %f", out2, float64(test.in)) } dec := msgpack.NewDecoder(bytes.NewReader(b)) v, err := dec.DecodeInterface() if err != nil { t.Fatal(err) } if v.(float32) != test.in { t.Fatalf("%f != %f", v, test.in) } var dst interface{} dst = float32(0) err = msgpack.Unmarshal(b, &dst) if err.Error() != "msgpack: Decode(non-pointer float32)" { t.Fatal(err) } } in := float32(math.NaN()) b, err := msgpack.Marshal(in) if err != nil { t.Fatal(err) } var out float32 err = msgpack.Unmarshal(b, &out) if err != nil { t.Fatal(err) } if !math.IsNaN(float64(out)) { t.Fatal("not NaN") } } func TestFloat64(t *testing.T) { table := []struct { in float64 wanted string }{ {0.1, "cb3fb999999999999a"}, {0.2, "cb3fc999999999999a"}, {-0.1, "cbbfb999999999999a"}, {-0.2, "cbbfc999999999999a"}, {math.Inf(1), "cb7ff0000000000000"}, {math.Inf(-1), "cbfff0000000000000"}, {math.MaxFloat64, "cb7fefffffffffffff"}, {math.SmallestNonzeroFloat64, "cb0000000000000001"}, } for _, test := range table { b, err := msgpack.Marshal(test.in) if err != nil { t.Fatal(err) } s := hex.EncodeToString(b) if s != test.wanted { t.Fatalf("%.32s != %.32s", s, test.wanted) } var out float64 err = msgpack.Unmarshal(b, &out) if err != nil { t.Fatal(err) } if out != test.in { t.Fatalf("%f != %f", out, test.in) } dec := msgpack.NewDecoder(bytes.NewReader(b)) v, err := dec.DecodeInterface() if err != nil { t.Fatal(err) } if v.(float64) != test.in { t.Fatalf("%f != %f", v, test.in) } var dst interface{} dst = float64(0) err = msgpack.Unmarshal(b, &dst) if err.Error() != "msgpack: Decode(non-pointer float64)" { t.Fatal(err) } } } func mustParseTime(format, s string) time.Time { tm, err := time.Parse(format, s) if err != nil { panic(err) } return tm } msgpack-5.3.5/unsafe.go000066400000000000000000000005551413451025300147640ustar00rootroot00000000000000// +build !appengine package msgpack import ( "unsafe" ) // bytesToString converts byte slice to string. func bytesToString(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } // stringToBytes converts string to byte slice. func stringToBytes(s string) []byte { return *(*[]byte)(unsafe.Pointer( &struct { string Cap int }{s, len(s)}, )) } msgpack-5.3.5/version.go000066400000000000000000000001461413451025300151640ustar00rootroot00000000000000package msgpack // Version is the current release version. func Version() string { return "5.3.5" }