Bump github.com/hashicorp/terraform-plugin-sdk/v2 from 2.26.1 to 2.27.0
Bumps [github.com/hashicorp/terraform-plugin-sdk/v2](https://github.com/hashicorp/terraform-plugin-sdk) from 2.26.1 to 2.27.0. - [Release notes](https://github.com/hashicorp/terraform-plugin-sdk/releases) - [Changelog](https://github.com/hashicorp/terraform-plugin-sdk/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/terraform-plugin-sdk/compare/v2.26.1...v2.27.0) --- updated-dependencies: - dependency-name: github.com/hashicorp/terraform-plugin-sdk/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
12
vendor/github.com/vmihailenco/msgpack/v4/.golangci.yml
generated
vendored
12
vendor/github.com/vmihailenco/msgpack/v4/.golangci.yml
generated
vendored
@ -1,12 +0,0 @@
|
||||
run:
|
||||
concurrency: 8
|
||||
deadline: 5m
|
||||
tests: false
|
||||
linters:
|
||||
enable-all: true
|
||||
disable:
|
||||
- gochecknoglobals
|
||||
- gocognit
|
||||
- godox
|
||||
- wsl
|
||||
- funlen
|
72
vendor/github.com/vmihailenco/msgpack/v4/README.md
generated
vendored
72
vendor/github.com/vmihailenco/msgpack/v4/README.md
generated
vendored
@ -1,72 +0,0 @@
|
||||
# MessagePack encoding for Golang
|
||||
|
||||
[](https://travis-ci.org/vmihailenco/msgpack)
|
||||
[](https://godoc.org/github.com/vmihailenco/msgpack)
|
||||
|
||||
Supports:
|
||||
- Primitives, arrays, maps, structs, time.Time and interface{}.
|
||||
- Appengine *datastore.Key and datastore.Cursor.
|
||||
- [CustomEncoder](https://godoc.org/github.com/vmihailenco/msgpack#example-CustomEncoder)/CustomDecoder interfaces for custom encoding.
|
||||
- [Extensions](https://godoc.org/github.com/vmihailenco/msgpack#example-RegisterExt) to encode type information.
|
||||
- Renaming fields via `msgpack:"my_field_name"` and alias via `msgpack:"alias:another_name"`.
|
||||
- Omitting individual empty fields via `msgpack:",omitempty"` tag or all [empty fields in a struct](https://godoc.org/github.com/vmihailenco/msgpack#example-Marshal--OmitEmpty).
|
||||
- [Map keys sorting](https://godoc.org/github.com/vmihailenco/msgpack#Encoder.SortMapKeys).
|
||||
- Encoding/decoding all [structs as arrays](https://godoc.org/github.com/vmihailenco/msgpack#Encoder.UseArrayForStructs) or [individual structs](https://godoc.org/github.com/vmihailenco/msgpack#example-Marshal--AsArray).
|
||||
- [Encoder.UseJSONTag](https://godoc.org/github.com/vmihailenco/msgpack#Encoder.UseJSONTag) with [Decoder.UseJSONTag](https://godoc.org/github.com/vmihailenco/msgpack#Decoder.UseJSONTag) can turn msgpack into drop-in replacement for JSON.
|
||||
- Simple but very fast and efficient [queries](https://godoc.org/github.com/vmihailenco/msgpack#example-Decoder-Query).
|
||||
|
||||
API docs: https://godoc.org/github.com/vmihailenco/msgpack.
|
||||
Examples: https://godoc.org/github.com/vmihailenco/msgpack#pkg-examples.
|
||||
|
||||
## Installation
|
||||
|
||||
This project uses [Go Modules](https://github.com/golang/go/wiki/Modules) and semantic import versioning since v4:
|
||||
|
||||
``` shell
|
||||
go mod init github.com/my/repo
|
||||
go get github.com/vmihailenco/msgpack/v4
|
||||
```
|
||||
|
||||
## Quickstart
|
||||
|
||||
``` go
|
||||
import "github.com/vmihailenco/msgpack/v4"
|
||||
|
||||
func ExampleMarshal() {
|
||||
type Item struct {
|
||||
Foo string
|
||||
}
|
||||
|
||||
b, err := msgpack.Marshal(&Item{Foo: "bar"})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var item Item
|
||||
err = msgpack.Unmarshal(b, &item)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(item.Foo)
|
||||
// Output: bar
|
||||
}
|
||||
```
|
||||
|
||||
## Benchmark
|
||||
|
||||
```
|
||||
BenchmarkStructVmihailencoMsgpack-4 200000 12814 ns/op 2128 B/op 26 allocs/op
|
||||
BenchmarkStructUgorjiGoMsgpack-4 100000 17678 ns/op 3616 B/op 70 allocs/op
|
||||
BenchmarkStructUgorjiGoCodec-4 100000 19053 ns/op 7346 B/op 23 allocs/op
|
||||
BenchmarkStructJSON-4 20000 69438 ns/op 7864 B/op 26 allocs/op
|
||||
BenchmarkStructGOB-4 10000 104331 ns/op 14664 B/op 278 allocs/op
|
||||
```
|
||||
|
||||
## Howto
|
||||
|
||||
Please go through [examples](https://godoc.org/github.com/vmihailenco/msgpack#pkg-examples) to get an idea how to use this package.
|
||||
|
||||
## See also
|
||||
|
||||
- [Golang PostgreSQL ORM](https://github.com/go-pg/pg)
|
||||
- [Golang message task queue](https://github.com/vmihailenco/taskq)
|
64
vendor/github.com/vmihailenco/msgpack/v4/appengine.go
generated
vendored
64
vendor/github.com/vmihailenco/msgpack/v4/appengine.go
generated
vendored
@ -1,64 +0,0 @@
|
||||
// +build appengine
|
||||
|
||||
package msgpack
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
ds "google.golang.org/appengine/datastore"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register((*ds.Key)(nil), encodeDatastoreKeyValue, decodeDatastoreKeyValue)
|
||||
Register((*ds.Cursor)(nil), encodeDatastoreCursorValue, decodeDatastoreCursorValue)
|
||||
}
|
||||
|
||||
func EncodeDatastoreKey(e *Encoder, key *ds.Key) error {
|
||||
if key == nil {
|
||||
return e.EncodeNil()
|
||||
}
|
||||
return e.EncodeString(key.Encode())
|
||||
}
|
||||
|
||||
func encodeDatastoreKeyValue(e *Encoder, v reflect.Value) error {
|
||||
key := v.Interface().(*ds.Key)
|
||||
return EncodeDatastoreKey(e, key)
|
||||
}
|
||||
|
||||
func DecodeDatastoreKey(d *Decoder) (*ds.Key, error) {
|
||||
v, err := d.DecodeString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if v == "" {
|
||||
return nil, nil
|
||||
}
|
||||
return ds.DecodeKey(v)
|
||||
}
|
||||
|
||||
func decodeDatastoreKeyValue(d *Decoder, v reflect.Value) error {
|
||||
key, err := DecodeDatastoreKey(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Set(reflect.ValueOf(key))
|
||||
return nil
|
||||
}
|
||||
|
||||
func encodeDatastoreCursorValue(e *Encoder, v reflect.Value) error {
|
||||
cursor := v.Interface().(ds.Cursor)
|
||||
return e.Encode(cursor.String())
|
||||
}
|
||||
|
||||
func decodeDatastoreCursorValue(d *Decoder, v reflect.Value) error {
|
||||
s, err := d.DecodeString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cursor, err := ds.DecodeCursor(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Set(reflect.ValueOf(cursor))
|
||||
return nil
|
||||
}
|
90
vendor/github.com/vmihailenco/msgpack/v4/codes/codes.go
generated
vendored
90
vendor/github.com/vmihailenco/msgpack/v4/codes/codes.go
generated
vendored
@ -1,90 +0,0 @@
|
||||
package codes
|
||||
|
||||
type Code byte
|
||||
|
||||
var (
|
||||
PosFixedNumHigh Code = 0x7f
|
||||
NegFixedNumLow Code = 0xe0
|
||||
|
||||
Nil Code = 0xc0
|
||||
|
||||
False Code = 0xc2
|
||||
True Code = 0xc3
|
||||
|
||||
Float Code = 0xca
|
||||
Double Code = 0xcb
|
||||
|
||||
Uint8 Code = 0xcc
|
||||
Uint16 Code = 0xcd
|
||||
Uint32 Code = 0xce
|
||||
Uint64 Code = 0xcf
|
||||
|
||||
Int8 Code = 0xd0
|
||||
Int16 Code = 0xd1
|
||||
Int32 Code = 0xd2
|
||||
Int64 Code = 0xd3
|
||||
|
||||
FixedStrLow Code = 0xa0
|
||||
FixedStrHigh Code = 0xbf
|
||||
FixedStrMask Code = 0x1f
|
||||
Str8 Code = 0xd9
|
||||
Str16 Code = 0xda
|
||||
Str32 Code = 0xdb
|
||||
|
||||
Bin8 Code = 0xc4
|
||||
Bin16 Code = 0xc5
|
||||
Bin32 Code = 0xc6
|
||||
|
||||
FixedArrayLow Code = 0x90
|
||||
FixedArrayHigh Code = 0x9f
|
||||
FixedArrayMask Code = 0xf
|
||||
Array16 Code = 0xdc
|
||||
Array32 Code = 0xdd
|
||||
|
||||
FixedMapLow Code = 0x80
|
||||
FixedMapHigh Code = 0x8f
|
||||
FixedMapMask Code = 0xf
|
||||
Map16 Code = 0xde
|
||||
Map32 Code = 0xdf
|
||||
|
||||
FixExt1 Code = 0xd4
|
||||
FixExt2 Code = 0xd5
|
||||
FixExt4 Code = 0xd6
|
||||
FixExt8 Code = 0xd7
|
||||
FixExt16 Code = 0xd8
|
||||
Ext8 Code = 0xc7
|
||||
Ext16 Code = 0xc8
|
||||
Ext32 Code = 0xc9
|
||||
)
|
||||
|
||||
func IsFixedNum(c Code) bool {
|
||||
return c <= PosFixedNumHigh || c >= NegFixedNumLow
|
||||
}
|
||||
|
||||
func IsFixedMap(c Code) bool {
|
||||
return c >= FixedMapLow && c <= FixedMapHigh
|
||||
}
|
||||
|
||||
func IsFixedArray(c Code) bool {
|
||||
return c >= FixedArrayLow && c <= FixedArrayHigh
|
||||
}
|
||||
|
||||
func IsFixedString(c Code) bool {
|
||||
return c >= FixedStrLow && c <= FixedStrHigh
|
||||
}
|
||||
|
||||
func IsString(c Code) bool {
|
||||
return IsFixedString(c) || c == Str8 || c == Str16 || c == Str32
|
||||
}
|
||||
|
||||
func IsBin(c Code) bool {
|
||||
return c == Bin8 || c == Bin16 || c == Bin32
|
||||
}
|
||||
|
||||
func IsFixedExt(c Code) bool {
|
||||
return c >= FixExt1 && c <= FixExt16
|
||||
}
|
||||
|
||||
func IsExt(c Code) bool {
|
||||
return IsFixedExt(c) || c == Ext8 || c == Ext16 || c == Ext32
|
||||
}
|
244
vendor/github.com/vmihailenco/msgpack/v4/ext.go
generated
vendored
244
vendor/github.com/vmihailenco/msgpack/v4/ext.go
generated
vendored
@ -1,244 +0,0 @@
|
||||
package msgpack
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
)
|
||||
|
||||
type extInfo struct {
|
||||
Type reflect.Type
|
||||
Decoder decoderFunc
|
||||
}
|
||||
|
||||
var extTypes = make(map[int8]*extInfo)
|
||||
|
||||
var bufferPool = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
}
|
||||
|
||||
// RegisterExt records a type, identified by a value for that type,
|
||||
// under the provided id. That id will identify the concrete type of a value
|
||||
// sent or received as an interface variable. Only types that will be
|
||||
// transferred as implementations of interface values need to be registered.
|
||||
// Expecting to be used only during initialization, it panics if the mapping
|
||||
// between types and ids is not a bijection.
|
||||
func RegisterExt(id int8, value interface{}) {
|
||||
typ := reflect.TypeOf(value)
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
ptr := reflect.PtrTo(typ)
|
||||
|
||||
if _, ok := extTypes[id]; ok {
|
||||
panic(fmt.Errorf("msgpack: ext with id=%d is already registered", id))
|
||||
}
|
||||
|
||||
registerExt(id, ptr, getEncoder(ptr), getDecoder(ptr))
|
||||
registerExt(id, typ, getEncoder(typ), getDecoder(typ))
|
||||
}
|
||||
|
||||
func registerExt(id int8, typ reflect.Type, enc encoderFunc, dec decoderFunc) {
|
||||
if enc != nil {
|
||||
typeEncMap.Store(typ, makeExtEncoder(id, enc))
|
||||
}
|
||||
if dec != nil {
|
||||
extTypes[id] = &extInfo{
|
||||
Type: typ,
|
||||
Decoder: dec,
|
||||
}
|
||||
typeDecMap.Store(typ, makeExtDecoder(id, dec))
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Encoder) EncodeExtHeader(typeID int8, length int) error {
|
||||
if err := e.encodeExtLen(length); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.w.WriteByte(byte(typeID)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeExtEncoder(typeID int8, enc encoderFunc) encoderFunc {
|
||||
return func(e *Encoder, v reflect.Value) error {
|
||||
buf := bufferPool.Get().(*bytes.Buffer)
|
||||
defer bufferPool.Put(buf)
|
||||
buf.Reset()
|
||||
|
||||
oldw := e.w
|
||||
e.w = buf
|
||||
err := enc(e, v)
|
||||
e.w = oldw
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = e.EncodeExtHeader(typeID, buf.Len())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return e.write(buf.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
func makeExtDecoder(typeID int8, dec decoderFunc) decoderFunc {
|
||||
return func(d *Decoder, v reflect.Value) error {
|
||||
c, err := d.PeekCode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !codes.IsExt(c) {
|
||||
return dec(d, v)
|
||||
}
|
||||
|
||||
id, extLen, err := d.DecodeExtHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if id != typeID {
|
||||
return fmt.Errorf("msgpack: got ext type=%d, wanted %d", id, typeID)
|
||||
}
|
||||
|
||||
d.extLen = extLen
|
||||
return dec(d, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeExtLen(l int) error {
|
||||
switch l {
|
||||
case 1:
|
||||
return e.writeCode(codes.FixExt1)
|
||||
case 2:
|
||||
return e.writeCode(codes.FixExt2)
|
||||
case 4:
|
||||
return e.writeCode(codes.FixExt4)
|
||||
case 8:
|
||||
return e.writeCode(codes.FixExt8)
|
||||
case 16:
|
||||
return e.writeCode(codes.FixExt16)
|
||||
}
|
||||
if l < 256 {
|
||||
return e.write1(codes.Ext8, uint8(l))
|
||||
}
|
||||
if l < 65536 {
|
||||
return e.write2(codes.Ext16, uint16(l))
|
||||
}
|
||||
return e.write4(codes.Ext32, uint32(l))
|
||||
}
|
||||
|
||||
func (d *Decoder) parseExtLen(c codes.Code) (int, error) {
|
||||
switch c {
|
||||
case codes.FixExt1:
|
||||
return 1, nil
|
||||
case codes.FixExt2:
|
||||
return 2, nil
|
||||
case codes.FixExt4:
|
||||
return 4, nil
|
||||
case codes.FixExt8:
|
||||
return 8, nil
|
||||
case codes.FixExt16:
|
||||
return 16, nil
|
||||
case codes.Ext8:
|
||||
n, err := d.uint8()
|
||||
return int(n), err
|
||||
case codes.Ext16:
|
||||
n, err := d.uint16()
|
||||
return int(n), err
|
||||
case codes.Ext32:
|
||||
n, err := d.uint32()
|
||||
return int(n), err
|
||||
default:
|
||||
return 0, fmt.Errorf("msgpack: invalid code=%x decoding ext length", c)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Decoder) extHeader(c codes.Code) (int8, int, error) {
|
||||
length, err := d.parseExtLen(c)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
typeID, err := d.readCode()
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
return int8(typeID), length, nil
|
||||
}
|
||||
|
||||
func (d *Decoder) DecodeExtHeader() (typeID int8, length int, err error) {
|
||||
c, err := d.readCode()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return d.extHeader(c)
|
||||
}
|
||||
|
||||
func (d *Decoder) extInterface(c codes.Code) (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)
|
||||
|
||||
d.extLen = extLen
|
||||
err = info.Decoder(d, v.Elem())
|
||||
d.extLen = 0
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return v.Interface(), nil
|
||||
}
|
||||
|
||||
func (d *Decoder) skipExt(c codes.Code) error {
|
||||
n, err := d.parseExtLen(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.skipN(n + 1)
|
||||
}
|
||||
|
||||
func (d *Decoder) skipExtHeader(c codes.Code) error {
|
||||
// Read ext type.
|
||||
_, err := d.readCode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Read ext body len.
|
||||
for i := 0; i < extHeaderLen(c); i++ {
|
||||
_, err := d.readCode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func extHeaderLen(c codes.Code) int {
|
||||
switch c {
|
||||
case codes.Ext8:
|
||||
return 1
|
||||
case codes.Ext16:
|
||||
return 2
|
||||
case codes.Ext32:
|
||||
return 4
|
||||
}
|
||||
return 0
|
||||
}
|
236
vendor/github.com/vmihailenco/msgpack/v4/intern.go
generated
vendored
236
vendor/github.com/vmihailenco/msgpack/v4/intern.go
generated
vendored
@ -1,236 +0,0 @@
|
||||
package msgpack
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
)
|
||||
|
||||
var internStringExtID int8 = -128
|
||||
|
||||
var errUnexpectedCode = errors.New("msgpack: unexpected code")
|
||||
|
||||
func encodeInternInterfaceValue(e *Encoder, v reflect.Value) error {
|
||||
if v.IsNil() {
|
||||
return e.EncodeNil()
|
||||
}
|
||||
|
||||
v = v.Elem()
|
||||
if v.Kind() == reflect.String {
|
||||
return encodeInternStringValue(e, v)
|
||||
}
|
||||
return e.EncodeValue(v)
|
||||
}
|
||||
|
||||
func encodeInternStringValue(e *Encoder, v reflect.Value) error {
|
||||
s := v.String()
|
||||
|
||||
if s != "" {
|
||||
if idx, ok := e.intern[s]; ok {
|
||||
return e.internStringIndex(idx)
|
||||
}
|
||||
|
||||
if e.intern == nil {
|
||||
e.intern = make(map[string]int)
|
||||
}
|
||||
|
||||
idx := len(e.intern)
|
||||
e.intern[s] = idx
|
||||
}
|
||||
|
||||
return e.EncodeString(s)
|
||||
}
|
||||
|
||||
func (e *Encoder) internStringIndex(idx int) error {
|
||||
if idx < math.MaxUint8 {
|
||||
if err := e.writeCode(codes.FixExt1); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.w.WriteByte(byte(internStringExtID)); err != nil {
|
||||
return err
|
||||
}
|
||||
return e.w.WriteByte(byte(idx))
|
||||
}
|
||||
|
||||
if idx < math.MaxUint16 {
|
||||
if err := e.writeCode(codes.FixExt2); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.w.WriteByte(byte(internStringExtID)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.w.WriteByte(byte(idx >> 8)); err != nil {
|
||||
return err
|
||||
}
|
||||
return e.w.WriteByte(byte(idx))
|
||||
}
|
||||
|
||||
if int64(idx) < math.MaxUint32 {
|
||||
if err := e.writeCode(codes.FixExt4); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.w.WriteByte(byte(internStringExtID)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.w.WriteByte(byte(idx >> 24)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.w.WriteByte(byte(idx >> 16)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.w.WriteByte(byte(idx >> 8)); err != nil {
|
||||
return err
|
||||
}
|
||||
return e.w.WriteByte(byte(idx))
|
||||
}
|
||||
|
||||
return fmt.Errorf("msgpack: intern string index=%d is too large", idx)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
func decodeInternInterfaceValue(d *Decoder, v reflect.Value) error {
|
||||
c, err := d.readCode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := d.internString(c)
|
||||
if err == nil {
|
||||
v.Set(reflect.ValueOf(s))
|
||||
return nil
|
||||
}
|
||||
if err != nil && err != errUnexpectedCode {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := d.s.UnreadByte(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return decodeInterfaceValue(d, v)
|
||||
}
|
||||
|
||||
func decodeInternStringValue(d *Decoder, v reflect.Value) error {
|
||||
if err := mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := d.readCode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := d.internString(c)
|
||||
if err != nil {
|
||||
if err == errUnexpectedCode {
|
||||
return fmt.Errorf("msgpack: invalid code=%x decoding intern string", c)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
v.SetString(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) internString(c codes.Code) (string, error) {
|
||||
if codes.IsFixedString(c) {
|
||||
n := int(c & codes.FixedStrMask)
|
||||
return d.internStringWithLen(n)
|
||||
}
|
||||
|
||||
switch c {
|
||||
case codes.FixExt1, codes.FixExt2, codes.FixExt4:
|
||||
typeID, length, err := d.extHeader(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if typeID != internStringExtID {
|
||||
err := fmt.Errorf("msgpack: got ext type=%d, wanted %d",
|
||||
typeID, internStringExtID)
|
||||
return "", err
|
||||
}
|
||||
|
||||
idx, err := d.internStringIndex(length)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return d.internStringAtIndex(idx)
|
||||
case codes.Str8, codes.Bin8:
|
||||
n, err := d.uint8()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return d.internStringWithLen(int(n))
|
||||
case codes.Str16, codes.Bin16:
|
||||
n, err := d.uint16()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return d.internStringWithLen(int(n))
|
||||
case codes.Str32, codes.Bin32:
|
||||
n, err := d.uint32()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return d.internStringWithLen(int(n))
|
||||
}
|
||||
|
||||
return "", errUnexpectedCode
|
||||
}
|
||||
|
||||
func (d *Decoder) internStringIndex(length int) (int, error) {
|
||||
switch length {
|
||||
case 1:
|
||||
c, err := d.s.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(c), nil
|
||||
case 2:
|
||||
b, err := d.readN(2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n := binary.BigEndian.Uint16(b)
|
||||
return int(n), nil
|
||||
case 4:
|
||||
b, err := d.readN(4)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n := binary.BigEndian.Uint32(b)
|
||||
return int(n), nil
|
||||
}
|
||||
|
||||
err := fmt.Errorf("msgpack: unsupported intern string index length=%d", length)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
func (d *Decoder) internStringAtIndex(idx int) (string, error) {
|
||||
if idx >= len(d.intern) {
|
||||
err := fmt.Errorf("msgpack: intern string with index=%d does not exist", idx)
|
||||
return "", err
|
||||
}
|
||||
return d.intern[idx], nil
|
||||
}
|
||||
|
||||
func (d *Decoder) internStringWithLen(n int) (string, error) {
|
||||
if n <= 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
s, err := d.stringWithLen(n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
d.intern = append(d.intern, s)
|
||||
|
||||
return s, nil
|
||||
}
|
17
vendor/github.com/vmihailenco/msgpack/v4/msgpack.go
generated
vendored
17
vendor/github.com/vmihailenco/msgpack/v4/msgpack.go
generated
vendored
@ -1,17 +0,0 @@
|
||||
package msgpack
|
||||
|
||||
type Marshaler interface {
|
||||
MarshalMsgpack() ([]byte, error)
|
||||
}
|
||||
|
||||
type Unmarshaler interface {
|
||||
UnmarshalMsgpack([]byte) error
|
||||
}
|
||||
|
||||
type CustomEncoder interface {
|
||||
EncodeMsgpack(*Encoder) error
|
||||
}
|
||||
|
||||
type CustomDecoder interface {
|
||||
DecodeMsgpack(*Decoder) error
|
||||
}
|
4
vendor/github.com/vmihailenco/msgpack/v5/.prettierrc
generated
vendored
Normal file
4
vendor/github.com/vmihailenco/msgpack/v5/.prettierrc
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
semi: false
|
||||
singleQuote: true
|
||||
proseWrap: always
|
||||
printWidth: 100
|
@ -2,10 +2,8 @@ sudo: false
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
- 1.15.x
|
||||
- 1.16.x
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
@ -18,4 +16,5 @@ env:
|
||||
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.21.0
|
||||
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go
|
||||
env GOPATH)/bin v1.31.0
|
@ -1,8 +1,32 @@
|
||||
## [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.
|
||||
- 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.
|
||||
- Encoder changed to preserve type of numbers instead of chosing most compact encoding. The old
|
||||
behavior can be achieved with Encoder.UseCompactEncoding.
|
||||
|
||||
## v3.3
|
||||
|
||||
@ -16,9 +40,12 @@
|
||||
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
@ -1,6 +1,6 @@
|
||||
all:
|
||||
test:
|
||||
go test ./...
|
||||
go test ./... -short -race
|
||||
go test ./... -run=NONE -bench=. -benchmem
|
||||
env GOOS=linux GOARCH=386 go test ./...
|
||||
golangci-lint run
|
||||
go vet
|
86
vendor/github.com/vmihailenco/msgpack/v5/README.md
generated
vendored
Normal file
86
vendor/github.com/vmihailenco/msgpack/v5/README.md
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
# MessagePack encoding for Golang
|
||||
|
||||
[](https://travis-ci.org/vmihailenco/msgpack)
|
||||
[](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5)
|
||||
[](https://msgpack.uptrace.dev/)
|
||||
[](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
|
||||
}
|
||||
```
|
1
vendor/github.com/vmihailenco/msgpack/v5/commitlint.config.js
generated
vendored
Normal file
1
vendor/github.com/vmihailenco/msgpack/v5/commitlint.config.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = { extends: ['@commitlint/config-conventional'] }
|
@ -10,12 +10,11 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"github.com/vmihailenco/msgpack/v5/msgpcode"
|
||||
)
|
||||
|
||||
const (
|
||||
looseIfaceFlag uint32 = 1 << iota
|
||||
decodeUsingJSONFlag
|
||||
looseInterfaceDecodingFlag uint32 = 1 << iota
|
||||
disallowUnknownFieldsFlag
|
||||
)
|
||||
|
||||
@ -38,19 +37,27 @@ var decPool = sync.Pool{
|
||||
},
|
||||
}
|
||||
|
||||
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 := decPool.Get().(*Decoder)
|
||||
dec := GetDecoder()
|
||||
|
||||
if r, ok := dec.r.(*bytes.Reader); ok {
|
||||
r.Reset(data)
|
||||
} else {
|
||||
dec.Reset(bytes.NewReader(data))
|
||||
}
|
||||
dec.Reset(bytes.NewReader(data))
|
||||
err := dec.Decode(v)
|
||||
|
||||
decPool.Put(dec)
|
||||
PutDecoder(dec)
|
||||
|
||||
return err
|
||||
}
|
||||
@ -61,18 +68,18 @@ type Decoder struct {
|
||||
s io.ByteScanner
|
||||
buf []byte
|
||||
|
||||
extLen int
|
||||
rec []byte // accumulates read data if not nil
|
||||
rec []byte // accumulates read data if not nil
|
||||
|
||||
intern []string
|
||||
flags uint32
|
||||
decodeMapFunc func(*Decoder) (interface{}, error)
|
||||
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 MessagePack values requested. Buffering can be disabled
|
||||
// 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)
|
||||
@ -83,65 +90,77 @@ func NewDecoder(r io.Reader) *Decoder {
|
||||
// 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 if br, ok := d.r.(*bufio.Reader); ok {
|
||||
br.Reset(r)
|
||||
} else {
|
||||
br := bufio.NewReader(r)
|
||||
d.r = br
|
||||
d.s = br
|
||||
}
|
||||
|
||||
if d.intern != nil {
|
||||
d.intern = d.intern[:0]
|
||||
}
|
||||
|
||||
//TODO:
|
||||
//d.useLoose = false
|
||||
//d.useJSONTag = false
|
||||
//d.disallowUnknownFields = false
|
||||
//d.decodeMapFunc = nil
|
||||
}
|
||||
|
||||
func (d *Decoder) SetDecodeMapFunc(fn func(*Decoder) (interface{}, error)) {
|
||||
d.decodeMapFunc = fn
|
||||
func (d *Decoder) SetMapDecoder(fn func(*Decoder) (interface{}, error)) {
|
||||
d.mapDecoder = fn
|
||||
}
|
||||
|
||||
// UseDecodeInterfaceLoose causes decoder to use DecodeInterfaceLoose
|
||||
// UseLooseInterfaceDecoding causes decoder to use DecodeInterfaceLoose
|
||||
// to decode msgpack value into Go interface{}.
|
||||
func (d *Decoder) UseDecodeInterfaceLoose(on bool) *Decoder {
|
||||
func (d *Decoder) UseLooseInterfaceDecoding(on bool) {
|
||||
if on {
|
||||
d.flags |= looseIfaceFlag
|
||||
d.flags |= looseInterfaceDecodingFlag
|
||||
} else {
|
||||
d.flags &= ^looseIfaceFlag
|
||||
d.flags &= ^looseInterfaceDecodingFlag
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// UseJSONTag causes the Decoder to use json struct tag as fallback option
|
||||
// SetCustomStructTag causes the decoder to use the supplied tag as a fallback option
|
||||
// if there is no msgpack tag.
|
||||
func (d *Decoder) UseJSONTag(on bool) *Decoder {
|
||||
if on {
|
||||
d.flags |= decodeUsingJSONFlag
|
||||
} else {
|
||||
d.flags &= ^decodeUsingJSONFlag
|
||||
}
|
||||
return d
|
||||
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() {
|
||||
if true {
|
||||
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 {
|
||||
@ -250,12 +269,22 @@ func (d *Decoder) Decode(v interface{}) error {
|
||||
return errors.New("msgpack: Decode(nil)")
|
||||
}
|
||||
if vv.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("msgpack: Decode(nonsettable %T)", v)
|
||||
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.IsValid() {
|
||||
return fmt.Errorf("msgpack: Decode(nonsettable %T)", v)
|
||||
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)
|
||||
}
|
||||
|
||||
@ -269,7 +298,7 @@ func (d *Decoder) DecodeMulti(v ...interface{}) error {
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeInterfaceCond() (interface{}, error) {
|
||||
if d.flags&looseIfaceFlag != 0 {
|
||||
if d.flags&looseInterfaceDecodingFlag != 0 {
|
||||
return d.DecodeInterfaceLoose()
|
||||
}
|
||||
return d.DecodeInterface()
|
||||
@ -285,7 +314,7 @@ func (d *Decoder) DecodeNil() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c != codes.Nil {
|
||||
if c != msgpcode.Nil {
|
||||
return fmt.Errorf("msgpack: invalid code=%x decoding nil", c)
|
||||
}
|
||||
return nil
|
||||
@ -311,11 +340,14 @@ func (d *Decoder) DecodeBool() (bool, error) {
|
||||
return d.bool(c)
|
||||
}
|
||||
|
||||
func (d *Decoder) bool(c codes.Code) (bool, error) {
|
||||
if c == codes.False {
|
||||
func (d *Decoder) bool(c byte) (bool, error) {
|
||||
if c == msgpcode.Nil {
|
||||
return false, nil
|
||||
}
|
||||
if c == codes.True {
|
||||
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)
|
||||
@ -349,63 +381,63 @@ func (d *Decoder) DecodeInterface() (interface{}, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if codes.IsFixedNum(c) {
|
||||
if msgpcode.IsFixedNum(c) {
|
||||
return int8(c), nil
|
||||
}
|
||||
if codes.IsFixedMap(c) {
|
||||
if msgpcode.IsFixedMap(c) {
|
||||
err = d.s.UnreadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.DecodeMap()
|
||||
return d.decodeMapDefault()
|
||||
}
|
||||
if codes.IsFixedArray(c) {
|
||||
if msgpcode.IsFixedArray(c) {
|
||||
return d.decodeSlice(c)
|
||||
}
|
||||
if codes.IsFixedString(c) {
|
||||
if msgpcode.IsFixedString(c) {
|
||||
return d.string(c)
|
||||
}
|
||||
|
||||
switch c {
|
||||
case codes.Nil:
|
||||
case msgpcode.Nil:
|
||||
return nil, nil
|
||||
case codes.False, codes.True:
|
||||
case msgpcode.False, msgpcode.True:
|
||||
return d.bool(c)
|
||||
case codes.Float:
|
||||
case msgpcode.Float:
|
||||
return d.float32(c)
|
||||
case codes.Double:
|
||||
case msgpcode.Double:
|
||||
return d.float64(c)
|
||||
case codes.Uint8:
|
||||
case msgpcode.Uint8:
|
||||
return d.uint8()
|
||||
case codes.Uint16:
|
||||
case msgpcode.Uint16:
|
||||
return d.uint16()
|
||||
case codes.Uint32:
|
||||
case msgpcode.Uint32:
|
||||
return d.uint32()
|
||||
case codes.Uint64:
|
||||
case msgpcode.Uint64:
|
||||
return d.uint64()
|
||||
case codes.Int8:
|
||||
case msgpcode.Int8:
|
||||
return d.int8()
|
||||
case codes.Int16:
|
||||
case msgpcode.Int16:
|
||||
return d.int16()
|
||||
case codes.Int32:
|
||||
case msgpcode.Int32:
|
||||
return d.int32()
|
||||
case codes.Int64:
|
||||
case msgpcode.Int64:
|
||||
return d.int64()
|
||||
case codes.Bin8, codes.Bin16, codes.Bin32:
|
||||
case msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32:
|
||||
return d.bytes(c, nil)
|
||||
case codes.Str8, codes.Str16, codes.Str32:
|
||||
case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32:
|
||||
return d.string(c)
|
||||
case codes.Array16, codes.Array32:
|
||||
case msgpcode.Array16, msgpcode.Array32:
|
||||
return d.decodeSlice(c)
|
||||
case codes.Map16, codes.Map32:
|
||||
case msgpcode.Map16, msgpcode.Map32:
|
||||
err = d.s.UnreadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.DecodeMap()
|
||||
case codes.FixExt1, codes.FixExt2, codes.FixExt4, codes.FixExt8, codes.FixExt16,
|
||||
codes.Ext8, codes.Ext16, codes.Ext32:
|
||||
return d.extInterface(c)
|
||||
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)
|
||||
@ -415,55 +447,55 @@ func (d *Decoder) DecodeInterface() (interface{}, error) {
|
||||
// - 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 codes.IsFixedNum(c) {
|
||||
if msgpcode.IsFixedNum(c) {
|
||||
return int64(int8(c)), nil
|
||||
}
|
||||
if codes.IsFixedMap(c) {
|
||||
if msgpcode.IsFixedMap(c) {
|
||||
err = d.s.UnreadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.DecodeMap()
|
||||
return d.decodeMapDefault()
|
||||
}
|
||||
if codes.IsFixedArray(c) {
|
||||
if msgpcode.IsFixedArray(c) {
|
||||
return d.decodeSlice(c)
|
||||
}
|
||||
if codes.IsFixedString(c) {
|
||||
if msgpcode.IsFixedString(c) {
|
||||
return d.string(c)
|
||||
}
|
||||
|
||||
switch c {
|
||||
case codes.Nil:
|
||||
case msgpcode.Nil:
|
||||
return nil, nil
|
||||
case codes.False, codes.True:
|
||||
case msgpcode.False, msgpcode.True:
|
||||
return d.bool(c)
|
||||
case codes.Float, codes.Double:
|
||||
case msgpcode.Float, msgpcode.Double:
|
||||
return d.float64(c)
|
||||
case codes.Uint8, codes.Uint16, codes.Uint32, codes.Uint64:
|
||||
case msgpcode.Uint8, msgpcode.Uint16, msgpcode.Uint32, msgpcode.Uint64:
|
||||
return d.uint(c)
|
||||
case codes.Int8, codes.Int16, codes.Int32, codes.Int64:
|
||||
case msgpcode.Int8, msgpcode.Int16, msgpcode.Int32, msgpcode.Int64:
|
||||
return d.int(c)
|
||||
case codes.Bin8, codes.Bin16, codes.Bin32:
|
||||
return d.bytes(c, nil)
|
||||
case codes.Str8, codes.Str16, codes.Str32:
|
||||
case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32,
|
||||
msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32:
|
||||
return d.string(c)
|
||||
case codes.Array16, codes.Array32:
|
||||
case msgpcode.Array16, msgpcode.Array32:
|
||||
return d.decodeSlice(c)
|
||||
case codes.Map16, codes.Map32:
|
||||
case msgpcode.Map16, msgpcode.Map32:
|
||||
err = d.s.UnreadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.DecodeMap()
|
||||
case codes.FixExt1, codes.FixExt2, codes.FixExt4, codes.FixExt8, codes.FixExt16,
|
||||
codes.Ext8, codes.Ext16, codes.Ext32:
|
||||
return d.extInterface(c)
|
||||
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)
|
||||
@ -476,63 +508,78 @@ func (d *Decoder) Skip() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if codes.IsFixedNum(c) {
|
||||
if msgpcode.IsFixedNum(c) {
|
||||
return nil
|
||||
}
|
||||
if codes.IsFixedMap(c) {
|
||||
if msgpcode.IsFixedMap(c) {
|
||||
return d.skipMap(c)
|
||||
}
|
||||
if codes.IsFixedArray(c) {
|
||||
if msgpcode.IsFixedArray(c) {
|
||||
return d.skipSlice(c)
|
||||
}
|
||||
if codes.IsFixedString(c) {
|
||||
if msgpcode.IsFixedString(c) {
|
||||
return d.skipBytes(c)
|
||||
}
|
||||
|
||||
switch c {
|
||||
case codes.Nil, codes.False, codes.True:
|
||||
case msgpcode.Nil, msgpcode.False, msgpcode.True:
|
||||
return nil
|
||||
case codes.Uint8, codes.Int8:
|
||||
case msgpcode.Uint8, msgpcode.Int8:
|
||||
return d.skipN(1)
|
||||
case codes.Uint16, codes.Int16:
|
||||
case msgpcode.Uint16, msgpcode.Int16:
|
||||
return d.skipN(2)
|
||||
case codes.Uint32, codes.Int32, codes.Float:
|
||||
case msgpcode.Uint32, msgpcode.Int32, msgpcode.Float:
|
||||
return d.skipN(4)
|
||||
case codes.Uint64, codes.Int64, codes.Double:
|
||||
case msgpcode.Uint64, msgpcode.Int64, msgpcode.Double:
|
||||
return d.skipN(8)
|
||||
case codes.Bin8, codes.Bin16, codes.Bin32:
|
||||
case msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32:
|
||||
return d.skipBytes(c)
|
||||
case codes.Str8, codes.Str16, codes.Str32:
|
||||
case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32:
|
||||
return d.skipBytes(c)
|
||||
case codes.Array16, codes.Array32:
|
||||
case msgpcode.Array16, msgpcode.Array32:
|
||||
return d.skipSlice(c)
|
||||
case codes.Map16, codes.Map32:
|
||||
case msgpcode.Map16, msgpcode.Map32:
|
||||
return d.skipMap(c)
|
||||
case codes.FixExt1, codes.FixExt2, codes.FixExt4, codes.FixExt8, codes.FixExt16,
|
||||
codes.Ext8, codes.Ext16, codes.Ext32:
|
||||
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 contains list of available codes.
|
||||
func (d *Decoder) PeekCode() (codes.Code, error) {
|
||||
// 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 codes.Code(c), d.s.UnreadByte()
|
||||
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 == codes.Nil
|
||||
return err == nil && code == msgpcode.Nil
|
||||
}
|
||||
|
||||
func (d *Decoder) readCode() (codes.Code, error) {
|
||||
d.extLen = 0
|
||||
func (d *Decoder) readCode() (byte, error) {
|
||||
c, err := d.s.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -540,7 +587,7 @@ func (d *Decoder) readCode() (codes.Code, error) {
|
||||
if d.rec != nil {
|
||||
d.rec = append(d.rec, c)
|
||||
}
|
||||
return codes.Code(c), nil
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (d *Decoder) readFull(b []byte) error {
|
||||
@ -549,7 +596,6 @@ func (d *Decoder) readFull(b []byte) error {
|
||||
return err
|
||||
}
|
||||
if d.rec != nil {
|
||||
//TODO: read directly into d.rec?
|
||||
d.rec = append(d.rec, b...)
|
||||
}
|
||||
return nil
|
||||
@ -562,7 +608,7 @@ func (d *Decoder) readN(n int) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
if d.rec != nil {
|
||||
//TODO: read directly into d.rec?
|
||||
// TODO: read directly into d.rec?
|
||||
d.rec = append(d.rec, d.buf...)
|
||||
}
|
||||
return d.buf, nil
|
@ -5,9 +5,11 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"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()
|
||||
@ -19,13 +21,13 @@ var (
|
||||
)
|
||||
|
||||
func decodeMapValue(d *Decoder, v reflect.Value) error {
|
||||
size, err := d.DecodeMapLen()
|
||||
n, err := d.DecodeMapLen()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
typ := v.Type()
|
||||
if size == -1 {
|
||||
if n == -1 {
|
||||
v.Set(reflect.Zero(typ))
|
||||
return nil
|
||||
}
|
||||
@ -33,33 +35,18 @@ func decodeMapValue(d *Decoder, v reflect.Value) error {
|
||||
if v.IsNil() {
|
||||
v.Set(reflect.MakeMap(typ))
|
||||
}
|
||||
if size == 0 {
|
||||
if n == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return decodeMapValueSize(d, v, size)
|
||||
return d.decodeTypedMapValue(v, n)
|
||||
}
|
||||
|
||||
func decodeMapValueSize(d *Decoder, v reflect.Value, size int) error {
|
||||
typ := v.Type()
|
||||
keyType := typ.Key()
|
||||
valueType := typ.Elem()
|
||||
|
||||
for i := 0; i < size; 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)
|
||||
func (d *Decoder) decodeMapDefault() (interface{}, error) {
|
||||
if d.mapDecoder != nil {
|
||||
return d.mapDecoder(d)
|
||||
}
|
||||
|
||||
return nil
|
||||
return d.DecodeMap()
|
||||
}
|
||||
|
||||
// DecodeMapLen decodes map length. Length is -1 when map is nil.
|
||||
@ -69,7 +56,7 @@ func (d *Decoder) DecodeMapLen() (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if codes.IsExt(c) {
|
||||
if msgpcode.IsExt(c) {
|
||||
if err = d.skipExtHeader(c); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -82,37 +69,22 @@ func (d *Decoder) DecodeMapLen() (int, error) {
|
||||
return d.mapLen(c)
|
||||
}
|
||||
|
||||
func (d *Decoder) mapLen(c codes.Code) (int, error) {
|
||||
size, err := d._mapLen(c)
|
||||
err = expandInvalidCodeMapLenError(c, err)
|
||||
return size, err
|
||||
}
|
||||
|
||||
func (d *Decoder) _mapLen(c codes.Code) (int, error) {
|
||||
if c == codes.Nil {
|
||||
func (d *Decoder) mapLen(c byte) (int, error) {
|
||||
if c == msgpcode.Nil {
|
||||
return -1, nil
|
||||
}
|
||||
if c >= codes.FixedMapLow && c <= codes.FixedMapHigh {
|
||||
return int(c & codes.FixedMapMask), nil
|
||||
if c >= msgpcode.FixedMapLow && c <= msgpcode.FixedMapHigh {
|
||||
return int(c & msgpcode.FixedMapMask), nil
|
||||
}
|
||||
if c == codes.Map16 {
|
||||
if c == msgpcode.Map16 {
|
||||
size, err := d.uint16()
|
||||
return int(size), err
|
||||
}
|
||||
if c == codes.Map32 {
|
||||
if c == msgpcode.Map32 {
|
||||
size, err := d.uint32()
|
||||
return int(size), err
|
||||
}
|
||||
return 0, errInvalidCode
|
||||
}
|
||||
|
||||
var errInvalidCode = errors.New("invalid code")
|
||||
|
||||
func expandInvalidCodeMapLenError(c codes.Code, err error) error {
|
||||
if err == errInvalidCode {
|
||||
return fmt.Errorf("msgpack: invalid code=%x decoding map length", c)
|
||||
}
|
||||
return err
|
||||
return 0, unexpectedCodeError{code: c, hint: "map length"}
|
||||
}
|
||||
|
||||
func decodeMapStringStringValue(d *Decoder, v reflect.Value) error {
|
||||
@ -157,61 +129,79 @@ func decodeMapStringInterfaceValue(d *Decoder, v reflect.Value) error {
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeMapStringInterfacePtr(ptr *map[string]interface{}) error {
|
||||
n, err := d.DecodeMapLen()
|
||||
m, err := d.DecodeMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n == -1 {
|
||||
*ptr = nil
|
||||
return nil
|
||||
*ptr = m
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) DecodeMap() (map[string]interface{}, error) {
|
||||
n, err := d.DecodeMapLen()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m := *ptr
|
||||
if m == nil {
|
||||
*ptr = make(map[string]interface{}, min(n, maxMapSize))
|
||||
m = *ptr
|
||||
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 err
|
||||
return nil, err
|
||||
}
|
||||
mv, err := d.decodeInterfaceCond()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
m[mk] = mv
|
||||
}
|
||||
|
||||
return nil
|
||||
return m, nil
|
||||
}
|
||||
|
||||
var errUnsupportedMapKey = errors.New("msgpack: unsupported map key")
|
||||
|
||||
func (d *Decoder) DecodeMap() (interface{}, error) {
|
||||
if d.decodeMapFunc != nil {
|
||||
return d.decodeMapFunc(d)
|
||||
}
|
||||
|
||||
size, err := d.DecodeMapLen()
|
||||
func (d *Decoder) DecodeUntypedMap() (map[interface{}]interface{}, error) {
|
||||
n, err := d.DecodeMapLen()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if size == -1 {
|
||||
|
||||
if n == -1 {
|
||||
return nil, nil
|
||||
}
|
||||
if size == 0 {
|
||||
return make(map[string]interface{}), 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
|
||||
}
|
||||
|
||||
code, err := d.PeekCode()
|
||||
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 codes.IsString(code) || codes.IsBin(code) {
|
||||
return d.decodeMapStringInterfaceSize(size)
|
||||
if n <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
key, err := d.decodeInterfaceCond()
|
||||
@ -228,40 +218,44 @@ func (d *Decoder) DecodeMap() (interface{}, error) {
|
||||
valueType := reflect.TypeOf(value)
|
||||
|
||||
if !keyType.Comparable() {
|
||||
return nil, errUnsupportedMapKey
|
||||
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))
|
||||
size--
|
||||
|
||||
err = decodeMapValueSize(d, mapValue, size)
|
||||
if err != nil {
|
||||
n--
|
||||
if err := d.decodeTypedMapValue(mapValue, n); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mapValue.Interface(), nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeMapStringInterfaceSize(size int) (map[string]interface{}, error) {
|
||||
m := make(map[string]interface{}, min(size, maxMapSize))
|
||||
for i := 0; i < size; i++ {
|
||||
mk, err := d.DecodeString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
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, err := d.decodeInterfaceCond()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
mv := reflect.New(valueType).Elem()
|
||||
if err := d.DecodeValue(mv); err != nil {
|
||||
return err
|
||||
}
|
||||
m[mk] = mv
|
||||
|
||||
v.SetMapIndex(mk, mv)
|
||||
}
|
||||
return m, nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) skipMap(c codes.Code) error {
|
||||
func (d *Decoder) skipMap(c byte) error {
|
||||
n, err := d.mapLen(c)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -283,54 +277,45 @@ func decodeStructValue(d *Decoder, v reflect.Value) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var isArray bool
|
||||
|
||||
n, err := d._mapLen(c)
|
||||
if err != nil {
|
||||
var err2 error
|
||||
n, err2 = d.arrayLen(c)
|
||||
if err2 != nil {
|
||||
return expandInvalidCodeMapLenError(c, err)
|
||||
}
|
||||
isArray = true
|
||||
n, err := d.mapLen(c)
|
||||
if err == nil {
|
||||
return d.decodeStruct(v, n)
|
||||
}
|
||||
if n == -1 {
|
||||
if err = mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var err2 error
|
||||
n, err2 = d.arrayLen(c)
|
||||
if err2 != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if n <= 0 {
|
||||
v.Set(reflect.Zero(v.Type()))
|
||||
return nil
|
||||
}
|
||||
|
||||
var fields *fields
|
||||
if d.flags&decodeUsingJSONFlag != 0 {
|
||||
fields = jsonStructs.Fields(v.Type())
|
||||
} else {
|
||||
fields = structs.Fields(v.Type())
|
||||
fields := structs.Fields(v.Type(), d.structTag)
|
||||
if n != len(fields.List) {
|
||||
return errArrayStruct
|
||||
}
|
||||
|
||||
if isArray {
|
||||
for i, f := range fields.List {
|
||||
if i >= n {
|
||||
break
|
||||
}
|
||||
if err := f.DecodeValue(d, v); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range fields.List {
|
||||
if err := f.DecodeValue(d, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Skip extra values.
|
||||
for i := len(fields.List); i < n; i++ {
|
||||
if err := d.Skip(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
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.DecodeString()
|
||||
name, err := d.decodeStringTemp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -339,9 +324,13 @@ func decodeStructValue(d *Decoder, v reflect.Value) error {
|
||||
if err := f.DecodeValue(d, v); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if d.flags&disallowUnknownFieldsFlag != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if d.flags&disallowUnknownFieldsFlag != 0 {
|
||||
return fmt.Errorf("msgpack: unknown field %q", name)
|
||||
} else if err := d.Skip(); err != nil {
|
||||
}
|
||||
if err := d.Skip(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import (
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"github.com/vmihailenco/msgpack/v5/msgpcode"
|
||||
)
|
||||
|
||||
func (d *Decoder) skipN(n int) error {
|
||||
@ -18,7 +18,7 @@ func (d *Decoder) uint8() (uint8, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint8(c), nil
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (d *Decoder) int8() (int8, error) {
|
||||
@ -87,33 +87,33 @@ func (d *Decoder) DecodeUint64() (uint64, error) {
|
||||
return d.uint(c)
|
||||
}
|
||||
|
||||
func (d *Decoder) uint(c codes.Code) (uint64, error) {
|
||||
if c == codes.Nil {
|
||||
func (d *Decoder) uint(c byte) (uint64, error) {
|
||||
if c == msgpcode.Nil {
|
||||
return 0, nil
|
||||
}
|
||||
if codes.IsFixedNum(c) {
|
||||
if msgpcode.IsFixedNum(c) {
|
||||
return uint64(int8(c)), nil
|
||||
}
|
||||
switch c {
|
||||
case codes.Uint8:
|
||||
case msgpcode.Uint8:
|
||||
n, err := d.uint8()
|
||||
return uint64(n), err
|
||||
case codes.Int8:
|
||||
case msgpcode.Int8:
|
||||
n, err := d.int8()
|
||||
return uint64(n), err
|
||||
case codes.Uint16:
|
||||
case msgpcode.Uint16:
|
||||
n, err := d.uint16()
|
||||
return uint64(n), err
|
||||
case codes.Int16:
|
||||
case msgpcode.Int16:
|
||||
n, err := d.int16()
|
||||
return uint64(n), err
|
||||
case codes.Uint32:
|
||||
case msgpcode.Uint32:
|
||||
n, err := d.uint32()
|
||||
return uint64(n), err
|
||||
case codes.Int32:
|
||||
case msgpcode.Int32:
|
||||
n, err := d.int32()
|
||||
return uint64(n), err
|
||||
case codes.Uint64, codes.Int64:
|
||||
case msgpcode.Uint64, msgpcode.Int64:
|
||||
return d.uint64()
|
||||
}
|
||||
return 0, fmt.Errorf("msgpack: invalid code=%x decoding uint64", c)
|
||||
@ -129,33 +129,33 @@ func (d *Decoder) DecodeInt64() (int64, error) {
|
||||
return d.int(c)
|
||||
}
|
||||
|
||||
func (d *Decoder) int(c codes.Code) (int64, error) {
|
||||
if c == codes.Nil {
|
||||
func (d *Decoder) int(c byte) (int64, error) {
|
||||
if c == msgpcode.Nil {
|
||||
return 0, nil
|
||||
}
|
||||
if codes.IsFixedNum(c) {
|
||||
if msgpcode.IsFixedNum(c) {
|
||||
return int64(int8(c)), nil
|
||||
}
|
||||
switch c {
|
||||
case codes.Uint8:
|
||||
case msgpcode.Uint8:
|
||||
n, err := d.uint8()
|
||||
return int64(n), err
|
||||
case codes.Int8:
|
||||
case msgpcode.Int8:
|
||||
n, err := d.uint8()
|
||||
return int64(int8(n)), err
|
||||
case codes.Uint16:
|
||||
case msgpcode.Uint16:
|
||||
n, err := d.uint16()
|
||||
return int64(n), err
|
||||
case codes.Int16:
|
||||
case msgpcode.Int16:
|
||||
n, err := d.uint16()
|
||||
return int64(int16(n)), err
|
||||
case codes.Uint32:
|
||||
case msgpcode.Uint32:
|
||||
n, err := d.uint32()
|
||||
return int64(n), err
|
||||
case codes.Int32:
|
||||
case msgpcode.Int32:
|
||||
n, err := d.uint32()
|
||||
return int64(int32(n)), err
|
||||
case codes.Uint64, codes.Int64:
|
||||
case msgpcode.Uint64, msgpcode.Int64:
|
||||
n, err := d.uint64()
|
||||
return int64(n), err
|
||||
}
|
||||
@ -170,8 +170,8 @@ func (d *Decoder) DecodeFloat32() (float32, error) {
|
||||
return d.float32(c)
|
||||
}
|
||||
|
||||
func (d *Decoder) float32(c codes.Code) (float32, error) {
|
||||
if c == codes.Float {
|
||||
func (d *Decoder) float32(c byte) (float32, error) {
|
||||
if c == msgpcode.Float {
|
||||
n, err := d.uint32()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -195,15 +195,15 @@ func (d *Decoder) DecodeFloat64() (float64, error) {
|
||||
return d.float64(c)
|
||||
}
|
||||
|
||||
func (d *Decoder) float64(c codes.Code) (float64, error) {
|
||||
func (d *Decoder) float64(c byte) (float64, error) {
|
||||
switch c {
|
||||
case codes.Float:
|
||||
case msgpcode.Float:
|
||||
n, err := d.float32(c)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return float64(n), nil
|
||||
case codes.Double:
|
||||
case msgpcode.Double:
|
||||
n, err := d.uint64()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -263,9 +263,6 @@ func decodeFloat32Value(d *Decoder, v reflect.Value) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
v.SetFloat(float64(f))
|
||||
return nil
|
||||
}
|
||||
@ -275,9 +272,6 @@ func decodeFloat64Value(d *Decoder, v reflect.Value) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
v.SetFloat(f)
|
||||
return nil
|
||||
}
|
||||
@ -287,9 +281,6 @@ func decodeInt64Value(d *Decoder, v reflect.Value) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
v.SetInt(n)
|
||||
return nil
|
||||
}
|
||||
@ -299,9 +290,6 @@ func decodeUint64Value(d *Decoder, v reflect.Value) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
v.SetUint(n)
|
||||
return nil
|
||||
}
|
@ -5,7 +5,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"github.com/vmihailenco/msgpack/v5/msgpcode"
|
||||
)
|
||||
|
||||
type queryResult struct {
|
||||
@ -57,9 +57,9 @@ func (d *Decoder) query(q *queryResult) error {
|
||||
}
|
||||
|
||||
switch {
|
||||
case code == codes.Map16 || code == codes.Map32 || codes.IsFixedMap(code):
|
||||
case code == msgpcode.Map16 || code == msgpcode.Map32 || msgpcode.IsFixedMap(code):
|
||||
err = d.queryMapKey(q)
|
||||
case code == codes.Array16 || code == codes.Array32 || codes.IsFixedArray(code):
|
||||
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)
|
||||
@ -77,12 +77,12 @@ func (d *Decoder) queryMapKey(q *queryResult) error {
|
||||
}
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
k, err := d.bytesNoCopy()
|
||||
key, err := d.decodeStringTemp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if string(k) == q.key {
|
||||
if key == q.key {
|
||||
if err := d.query(q); err != nil {
|
||||
return err
|
||||
}
|
@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"github.com/vmihailenco/msgpack/v5/msgpcode"
|
||||
)
|
||||
|
||||
var sliceStringPtrType = reflect.TypeOf((*[]string)(nil))
|
||||
@ -18,17 +18,17 @@ func (d *Decoder) DecodeArrayLen() (int, error) {
|
||||
return d.arrayLen(c)
|
||||
}
|
||||
|
||||
func (d *Decoder) arrayLen(c codes.Code) (int, error) {
|
||||
if c == codes.Nil {
|
||||
func (d *Decoder) arrayLen(c byte) (int, error) {
|
||||
if c == msgpcode.Nil {
|
||||
return -1, nil
|
||||
} else if c >= codes.FixedArrayLow && c <= codes.FixedArrayHigh {
|
||||
return int(c & codes.FixedArrayMask), nil
|
||||
} else if c >= msgpcode.FixedArrayLow && c <= msgpcode.FixedArrayHigh {
|
||||
return int(c & msgpcode.FixedArrayMask), nil
|
||||
}
|
||||
switch c {
|
||||
case codes.Array16:
|
||||
case msgpcode.Array16:
|
||||
n, err := d.uint16()
|
||||
return int(n), err
|
||||
case codes.Array32:
|
||||
case msgpcode.Array32:
|
||||
n, err := d.uint32()
|
||||
return int(n), err
|
||||
}
|
||||
@ -154,7 +154,7 @@ func (d *Decoder) DecodeSlice() ([]interface{}, error) {
|
||||
return d.decodeSlice(c)
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeSlice(c codes.Code) ([]interface{}, error) {
|
||||
func (d *Decoder) decodeSlice(c byte) ([]interface{}, error) {
|
||||
n, err := d.arrayLen(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -175,7 +175,7 @@ func (d *Decoder) decodeSlice(c codes.Code) ([]interface{}, error) {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (d *Decoder) skipSlice(c codes.Code) error {
|
||||
func (d *Decoder) skipSlice(c byte) error {
|
||||
n, err := d.arrayLen(c)
|
||||
if err != nil {
|
||||
return err
|
@ -4,34 +4,38 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"github.com/vmihailenco/msgpack/v5/msgpcode"
|
||||
)
|
||||
|
||||
func (d *Decoder) bytesLen(c codes.Code) (int, error) {
|
||||
if c == codes.Nil {
|
||||
func (d *Decoder) bytesLen(c byte) (int, error) {
|
||||
if c == msgpcode.Nil {
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
if codes.IsFixedString(c) {
|
||||
return int(c & codes.FixedStrMask), nil
|
||||
if msgpcode.IsFixedString(c) {
|
||||
return int(c & msgpcode.FixedStrMask), nil
|
||||
}
|
||||
|
||||
switch c {
|
||||
case codes.Str8, codes.Bin8:
|
||||
case msgpcode.Str8, msgpcode.Bin8:
|
||||
n, err := d.uint8()
|
||||
return int(n), err
|
||||
case codes.Str16, codes.Bin16:
|
||||
case msgpcode.Str16, msgpcode.Bin16:
|
||||
n, err := d.uint16()
|
||||
return int(n), err
|
||||
case codes.Str32, codes.Bin32:
|
||||
case msgpcode.Str32, msgpcode.Bin32:
|
||||
n, err := d.uint32()
|
||||
return int(n), err
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("msgpack: invalid code=%x decoding bytes length", c)
|
||||
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
|
||||
@ -39,7 +43,7 @@ func (d *Decoder) DecodeString() (string, error) {
|
||||
return d.string(c)
|
||||
}
|
||||
|
||||
func (d *Decoder) string(c codes.Code) (string, error) {
|
||||
func (d *Decoder) string(c byte) (string, error) {
|
||||
n, err := d.bytesLen(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -56,15 +60,10 @@ func (d *Decoder) stringWithLen(n int) (string, error) {
|
||||
}
|
||||
|
||||
func decodeStringValue(d *Decoder, v reflect.Value) error {
|
||||
if err := mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := d.DecodeString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v.SetString(s)
|
||||
return nil
|
||||
}
|
||||
@ -85,7 +84,7 @@ func (d *Decoder) DecodeBytes() ([]byte, error) {
|
||||
return d.bytes(c, nil)
|
||||
}
|
||||
|
||||
func (d *Decoder) bytes(c codes.Code, b []byte) ([]byte, error) {
|
||||
func (d *Decoder) bytes(c byte, b []byte) ([]byte, error) {
|
||||
n, err := d.bytesLen(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -96,19 +95,30 @@ func (d *Decoder) bytes(c codes.Code, b []byte) ([]byte, error) {
|
||||
return readN(d.r, b, n)
|
||||
}
|
||||
|
||||
func (d *Decoder) bytesNoCopy() ([]byte, error) {
|
||||
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 nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
n, err := d.bytesLen(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
if n == -1 {
|
||||
return nil, nil
|
||||
return "", nil
|
||||
}
|
||||
return d.readN(n)
|
||||
|
||||
b, err := d.readN(n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return bytesToString(b), nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeBytesPtr(ptr *[]byte) error {
|
||||
@ -119,7 +129,7 @@ func (d *Decoder) decodeBytesPtr(ptr *[]byte) error {
|
||||
return d.bytesPtr(c, ptr)
|
||||
}
|
||||
|
||||
func (d *Decoder) bytesPtr(c codes.Code, ptr *[]byte) error {
|
||||
func (d *Decoder) bytesPtr(c byte, ptr *[]byte) error {
|
||||
n, err := d.bytesLen(c)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -133,7 +143,7 @@ func (d *Decoder) bytesPtr(c codes.Code, ptr *[]byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Decoder) skipBytes(c codes.Code) error {
|
||||
func (d *Decoder) skipBytes(c byte) error {
|
||||
n, err := d.bytesLen(c)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -145,10 +155,6 @@ func (d *Decoder) skipBytes(c codes.Code) error {
|
||||
}
|
||||
|
||||
func decodeBytesValue(d *Decoder, v reflect.Value) error {
|
||||
if err := mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := d.readCode()
|
||||
if err != nil {
|
||||
return err
|
@ -7,8 +7,10 @@ import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
|
||||
var stringType = reflect.TypeOf((*string)(nil)).Elem()
|
||||
var (
|
||||
interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
|
||||
stringType = reflect.TypeOf((*string)(nil)).Elem()
|
||||
)
|
||||
|
||||
var valueDecoders []decoderFunc
|
||||
|
||||
@ -43,13 +45,6 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func mustSet(v reflect.Value) error {
|
||||
if !v.CanSet() {
|
||||
return fmt.Errorf("msgpack: Decode(nonsettable %s)", v.Type())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getDecoder(typ reflect.Type) decoderFunc {
|
||||
if v, ok := typeDecMap.Load(typ); ok {
|
||||
return v.(decoderFunc)
|
||||
@ -62,33 +57,45 @@ func getDecoder(typ reflect.Type) decoderFunc {
|
||||
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 decodeCustomValue
|
||||
return nilAwareDecoder(typ, decodeCustomValue)
|
||||
}
|
||||
if typ.Implements(unmarshalerType) {
|
||||
return unmarshalValue
|
||||
return nilAwareDecoder(typ, unmarshalValue)
|
||||
}
|
||||
if typ.Implements(binaryUnmarshalerType) {
|
||||
return unmarshalBinaryValue
|
||||
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 decodeCustomValueAddr
|
||||
return addrDecoder(nilAwareDecoder(typ, decodeCustomValue))
|
||||
}
|
||||
if ptr.Implements(unmarshalerType) {
|
||||
return unmarshalValueAddr
|
||||
return addrDecoder(nilAwareDecoder(typ, unmarshalValue))
|
||||
}
|
||||
if ptr.Implements(binaryUnmarshalerType) {
|
||||
return unmarshalBinaryValueAddr
|
||||
return addrDecoder(nilAwareDecoder(typ, unmarshalBinaryValue))
|
||||
}
|
||||
if ptr.Implements(textUnmarshalerType) {
|
||||
return addrDecoder(nilAwareDecoder(typ, unmarshalTextValue))
|
||||
}
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case reflect.Ptr:
|
||||
return ptrDecoderFunc(typ)
|
||||
return ptrValueDecoder(typ)
|
||||
case reflect.Slice:
|
||||
elem := typ.Elem()
|
||||
if elem.Kind() == reflect.Uint8 {
|
||||
@ -115,85 +122,50 @@ func _getDecoder(typ reflect.Type) decoderFunc {
|
||||
return valueDecoders[kind]
|
||||
}
|
||||
|
||||
func ptrDecoderFunc(typ reflect.Type) decoderFunc {
|
||||
func ptrValueDecoder(typ reflect.Type) decoderFunc {
|
||||
decoder := getDecoder(typ.Elem())
|
||||
return func(d *Decoder, v reflect.Value) error {
|
||||
if d.hasNilCode() {
|
||||
if err := mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
if !v.IsNil() {
|
||||
v.Set(reflect.Zero(v.Type()))
|
||||
}
|
||||
return d.DecodeNil()
|
||||
}
|
||||
if v.IsNil() {
|
||||
if err := mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
v.Set(reflect.New(v.Type().Elem()))
|
||||
}
|
||||
return decoder(d, v.Elem())
|
||||
}
|
||||
}
|
||||
|
||||
func decodeCustomValueAddr(d *Decoder, v reflect.Value) error {
|
||||
if !v.CanAddr() {
|
||||
return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface())
|
||||
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())
|
||||
}
|
||||
return decodeCustomValue(d, v.Addr())
|
||||
}
|
||||
|
||||
func decodeCustomValue(d *Decoder, v reflect.Value) error {
|
||||
if d.hasNilCode() {
|
||||
return d.decodeNilValue(v)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
if v.IsNil() {
|
||||
v.Set(reflect.New(v.Type().Elem()))
|
||||
}
|
||||
|
||||
decoder := v.Interface().(CustomDecoder)
|
||||
return decoder.DecodeMsgpack(d)
|
||||
}
|
||||
|
||||
func unmarshalValueAddr(d *Decoder, v reflect.Value) error {
|
||||
if !v.CanAddr() {
|
||||
return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface())
|
||||
}
|
||||
return unmarshalValue(d, v.Addr())
|
||||
}
|
||||
|
||||
func unmarshalValue(d *Decoder, v reflect.Value) error {
|
||||
if d.extLen == 0 || d.extLen == 1 {
|
||||
return func(d *Decoder, v reflect.Value) error {
|
||||
if d.hasNilCode() {
|
||||
return d.decodeNilValue(v)
|
||||
}
|
||||
return fn(d, v)
|
||||
}
|
||||
|
||||
if v.IsNil() {
|
||||
v.Set(reflect.New(v.Type().Elem()))
|
||||
}
|
||||
|
||||
var b []byte
|
||||
|
||||
if d.extLen != 0 {
|
||||
var err error
|
||||
b, err = d.readN(d.extLen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
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 decodeBoolValue(d *Decoder, v reflect.Value) error {
|
||||
@ -201,9 +173,6 @@ func decodeBoolValue(d *Decoder, v reflect.Value) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = mustSet(v); err != nil {
|
||||
return err
|
||||
}
|
||||
v.SetBool(flag)
|
||||
return nil
|
||||
}
|
||||
@ -212,16 +181,7 @@ func decodeInterfaceValue(d *Decoder, v reflect.Value) error {
|
||||
if v.IsNil() {
|
||||
return d.interfaceValue(v)
|
||||
}
|
||||
|
||||
elem := v.Elem()
|
||||
if !elem.CanAddr() {
|
||||
if d.hasNilCode() {
|
||||
v.Set(reflect.Zero(v.Type()))
|
||||
return d.DecodeNil()
|
||||
}
|
||||
}
|
||||
|
||||
return d.DecodeValue(elem)
|
||||
return d.DecodeValue(v.Elem())
|
||||
}
|
||||
|
||||
func (d *Decoder) interfaceValue(v reflect.Value) error {
|
||||
@ -250,22 +210,26 @@ func decodeUnsupportedValue(d *Decoder, v reflect.Value) error {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
func unmarshalBinaryValueAddr(d *Decoder, v reflect.Value) error {
|
||||
if !v.CanAddr() {
|
||||
return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface())
|
||||
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
|
||||
}
|
||||
return unmarshalBinaryValue(d, v.Addr())
|
||||
b = d.rec
|
||||
d.rec = nil
|
||||
|
||||
unmarshaler := v.Interface().(Unmarshaler)
|
||||
return unmarshaler.UnmarshalMsgpack(b)
|
||||
}
|
||||
|
||||
func unmarshalBinaryValue(d *Decoder, v reflect.Value) error {
|
||||
if d.hasNilCode() {
|
||||
return d.decodeNilValue(v)
|
||||
}
|
||||
|
||||
if v.IsNil() {
|
||||
v.Set(reflect.New(v.Type().Elem()))
|
||||
}
|
||||
|
||||
data, err := d.DecodeBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -274,3 +238,13 @@ func unmarshalBinaryValue(d *Decoder, v reflect.Value) error {
|
||||
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)
|
||||
}
|
@ -7,15 +7,16 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"github.com/vmihailenco/msgpack/v5/msgpcode"
|
||||
)
|
||||
|
||||
const (
|
||||
sortMapKeysFlag uint32 = 1 << iota
|
||||
structAsArrayFlag
|
||||
encodeUsingJSONFlag
|
||||
arrayEncodedStructsFlag
|
||||
useCompactIntsFlag
|
||||
useCompactFloatsFlag
|
||||
useInternedStringsFlag
|
||||
omitEmptyFlag
|
||||
)
|
||||
|
||||
type writer interface {
|
||||
@ -25,23 +26,16 @@ type writer interface {
|
||||
|
||||
type byteWriter struct {
|
||||
io.Writer
|
||||
|
||||
buf [1]byte
|
||||
}
|
||||
|
||||
func newByteWriter(w io.Writer) *byteWriter {
|
||||
bw := new(byteWriter)
|
||||
bw.Reset(w)
|
||||
return bw
|
||||
func newByteWriter(w io.Writer) byteWriter {
|
||||
return byteWriter{
|
||||
Writer: w,
|
||||
}
|
||||
}
|
||||
|
||||
func (bw *byteWriter) Reset(w io.Writer) {
|
||||
bw.Writer = w
|
||||
}
|
||||
|
||||
func (bw *byteWriter) WriteByte(c byte) error {
|
||||
bw.buf[0] = c
|
||||
_, err := bw.Write(bw.buf[:])
|
||||
func (bw byteWriter) WriteByte(c byte) error {
|
||||
_, err := bw.Write([]byte{c})
|
||||
return err
|
||||
}
|
||||
|
||||
@ -53,9 +47,18 @@ var encPool = sync.Pool{
|
||||
},
|
||||
}
|
||||
|
||||
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 := encPool.Get().(*Encoder)
|
||||
enc := GetEncoder()
|
||||
|
||||
var buf bytes.Buffer
|
||||
enc.Reset(&buf)
|
||||
@ -63,7 +66,7 @@ func Marshal(v interface{}) ([]byte, error) {
|
||||
err := enc.Encode(v)
|
||||
b := buf.Bytes()
|
||||
|
||||
encPool.Put(enc)
|
||||
PutEncoder(enc)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -74,49 +77,63 @@ func Marshal(v interface{}) ([]byte, error) {
|
||||
type Encoder struct {
|
||||
w writer
|
||||
|
||||
buf []byte
|
||||
timeBuf []byte
|
||||
bootstrap [9 + 12]byte
|
||||
buf []byte
|
||||
timeBuf []byte
|
||||
|
||||
intern map[string]int
|
||||
dict map[string]int
|
||||
|
||||
flags uint32
|
||||
flags uint32
|
||||
structTag string
|
||||
}
|
||||
|
||||
// NewEncoder returns a new encoder that writes to w.
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
e := new(Encoder)
|
||||
e.buf = e.bootstrap[:9]
|
||||
e.timeBuf = e.bootstrap[9 : 9+12]
|
||||
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 if bw, ok := e.w.(*byteWriter); ok {
|
||||
bw.Reset(w)
|
||||
} else {
|
||||
e.w = newByteWriter(w)
|
||||
}
|
||||
|
||||
for k := range e.intern {
|
||||
delete(e.intern, k)
|
||||
}
|
||||
|
||||
//TODO:
|
||||
//e.sortMapKeys = false
|
||||
//e.structAsArray = false
|
||||
//e.useJSONTag = false
|
||||
//e.useCompact = false
|
||||
}
|
||||
|
||||
// SortMapKeys causes the Encoder to encode map keys in increasing order.
|
||||
// SetSortMapKeys causes the Encoder to encode map keys in increasing order.
|
||||
// Supported map types are:
|
||||
// - map[string]string
|
||||
// - map[string]interface{}
|
||||
func (e *Encoder) SortMapKeys(on bool) *Encoder {
|
||||
func (e *Encoder) SetSortMapKeys(on bool) *Encoder {
|
||||
if on {
|
||||
e.flags |= sortMapKeysFlag
|
||||
} else {
|
||||
@ -125,36 +142,38 @@ func (e *Encoder) SortMapKeys(on bool) *Encoder {
|
||||
return e
|
||||
}
|
||||
|
||||
// StructAsArray causes the Encoder to encode Go structs as msgpack arrays.
|
||||
func (e *Encoder) StructAsArray(on bool) *Encoder {
|
||||
if on {
|
||||
e.flags |= structAsArrayFlag
|
||||
} else {
|
||||
e.flags &= ^structAsArrayFlag
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// UseJSONTag causes the Encoder to use json struct tag as fallback option
|
||||
// if there is no msgpack tag.
|
||||
func (e *Encoder) UseJSONTag(on bool) *Encoder {
|
||||
// SetOmitEmpty causes the Encoder to omit empty values by default.
|
||||
func (e *Encoder) SetOmitEmpty(on bool) {
|
||||
if on {
|
||||
e.flags |= encodeUsingJSONFlag
|
||||
e.flags |= omitEmptyFlag
|
||||
} else {
|
||||
e.flags &= ^encodeUsingJSONFlag
|
||||
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
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// 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) UseCompactEncoding(on bool) *Encoder {
|
||||
func (e *Encoder) UseCompactInts(on bool) {
|
||||
if on {
|
||||
e.flags |= useCompactIntsFlag
|
||||
} else {
|
||||
e.flags &= ^useCompactIntsFlag
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// UseCompactFloats causes the Encoder to chose a compact integer encoding
|
||||
@ -167,6 +186,15 @@ func (e *Encoder) UseCompactFloats(on bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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:
|
||||
@ -176,11 +204,11 @@ func (e *Encoder) Encode(v interface{}) error {
|
||||
case []byte:
|
||||
return e.EncodeBytes(v)
|
||||
case int:
|
||||
return e.encodeInt64Cond(int64(v))
|
||||
return e.EncodeInt(int64(v))
|
||||
case int64:
|
||||
return e.encodeInt64Cond(v)
|
||||
case uint:
|
||||
return e.encodeUint64Cond(uint64(v))
|
||||
return e.EncodeUint(uint64(v))
|
||||
case uint64:
|
||||
return e.encodeUint64Cond(v)
|
||||
case bool:
|
||||
@ -212,22 +240,22 @@ func (e *Encoder) EncodeValue(v reflect.Value) error {
|
||||
}
|
||||
|
||||
func (e *Encoder) EncodeNil() error {
|
||||
return e.writeCode(codes.Nil)
|
||||
return e.writeCode(msgpcode.Nil)
|
||||
}
|
||||
|
||||
func (e *Encoder) EncodeBool(value bool) error {
|
||||
if value {
|
||||
return e.writeCode(codes.True)
|
||||
return e.writeCode(msgpcode.True)
|
||||
}
|
||||
return e.writeCode(codes.False)
|
||||
return e.writeCode(msgpcode.False)
|
||||
}
|
||||
|
||||
func (e *Encoder) EncodeDuration(d time.Duration) error {
|
||||
return e.EncodeInt(int64(d))
|
||||
}
|
||||
|
||||
func (e *Encoder) writeCode(c codes.Code) error {
|
||||
return e.w.WriteByte(byte(c))
|
||||
func (e *Encoder) writeCode(c byte) error {
|
||||
return e.w.WriteByte(c)
|
||||
}
|
||||
|
||||
func (e *Encoder) write(b []byte) error {
|
@ -1,10 +1,11 @@
|
||||
package msgpack
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"github.com/vmihailenco/msgpack/v5/msgpcode"
|
||||
)
|
||||
|
||||
func encodeMapValue(e *Encoder, v reflect.Value) error {
|
||||
@ -16,11 +17,12 @@ func encodeMapValue(e *Encoder, v reflect.Value) error {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, key := range v.MapKeys() {
|
||||
if err := e.EncodeValue(key); err != nil {
|
||||
iter := v.MapRange()
|
||||
for iter.Next() {
|
||||
if err := e.EncodeValue(iter.Key()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.EncodeValue(v.MapIndex(key)); err != nil {
|
||||
if err := e.EncodeValue(iter.Value()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -58,16 +60,20 @@ func encodeMapStringInterfaceValue(e *Encoder, v reflect.Value) error {
|
||||
if v.IsNil() {
|
||||
return e.EncodeNil()
|
||||
}
|
||||
|
||||
if err := e.EncodeMapLen(v.Len()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := v.Convert(mapStringInterfaceType).Interface().(map[string]interface{})
|
||||
if e.flags&sortMapKeysFlag != 0 {
|
||||
return e.encodeSortedMapStringInterface(m)
|
||||
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
|
||||
@ -76,6 +82,33 @@ func encodeMapStringInterfaceValue(e *Encoder, v reflect.Value) error {
|
||||
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
|
||||
}
|
||||
@ -100,48 +133,22 @@ func (e *Encoder) encodeSortedMapStringString(m map[string]string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeSortedMapStringInterface(m map[string]interface{}) error {
|
||||
keys := make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, k := range keys {
|
||||
err := e.EncodeString(k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = e.Encode(m[k]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Encoder) EncodeMapLen(l int) error {
|
||||
if l < 16 {
|
||||
return e.writeCode(codes.FixedMapLow | codes.Code(l))
|
||||
return e.writeCode(msgpcode.FixedMapLow | byte(l))
|
||||
}
|
||||
if l < 65536 {
|
||||
return e.write2(codes.Map16, uint16(l))
|
||||
if l <= math.MaxUint16 {
|
||||
return e.write2(msgpcode.Map16, uint16(l))
|
||||
}
|
||||
return e.write4(codes.Map32, uint32(l))
|
||||
return e.write4(msgpcode.Map32, uint32(l))
|
||||
}
|
||||
|
||||
func encodeStructValue(e *Encoder, strct reflect.Value) error {
|
||||
var structFields *fields
|
||||
if e.flags&encodeUsingJSONFlag != 0 {
|
||||
structFields = jsonStructs.Fields(strct.Type())
|
||||
} else {
|
||||
structFields = structs.Fields(strct.Type())
|
||||
}
|
||||
|
||||
if e.flags&structAsArrayFlag != 0 || structFields.AsArray {
|
||||
structFields := structs.Fields(strct.Type(), e.structTag)
|
||||
if e.flags&arrayEncodedStructsFlag != 0 || structFields.AsArray {
|
||||
return encodeStructValueAsArray(e, strct, structFields.List)
|
||||
}
|
||||
fields := structFields.OmitEmpty(strct)
|
||||
fields := structFields.OmitEmpty(strct, e.flags&omitEmptyFlag != 0)
|
||||
|
||||
if err := e.EncodeMapLen(len(fields)); err != nil {
|
||||
return err
|
@ -4,12 +4,12 @@ import (
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"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(codes.Uint8, n)
|
||||
return e.write1(msgpcode.Uint8, n)
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeUint8Cond(n uint8) error {
|
||||
@ -21,7 +21,7 @@ func (e *Encoder) encodeUint8Cond(n uint8) error {
|
||||
|
||||
// EncodeUint16 encodes an uint16 in 3 bytes preserving type of the number.
|
||||
func (e *Encoder) EncodeUint16(n uint16) error {
|
||||
return e.write2(codes.Uint16, n)
|
||||
return e.write2(msgpcode.Uint16, n)
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeUint16Cond(n uint16) error {
|
||||
@ -33,7 +33,7 @@ func (e *Encoder) encodeUint16Cond(n uint16) error {
|
||||
|
||||
// EncodeUint32 encodes an uint16 in 5 bytes preserving type of the number.
|
||||
func (e *Encoder) EncodeUint32(n uint32) error {
|
||||
return e.write4(codes.Uint32, n)
|
||||
return e.write4(msgpcode.Uint32, n)
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeUint32Cond(n uint32) error {
|
||||
@ -45,7 +45,7 @@ func (e *Encoder) encodeUint32Cond(n uint32) error {
|
||||
|
||||
// EncodeUint64 encodes an uint16 in 9 bytes preserving type of the number.
|
||||
func (e *Encoder) EncodeUint64(n uint64) error {
|
||||
return e.write8(codes.Uint64, n)
|
||||
return e.write8(msgpcode.Uint64, n)
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeUint64Cond(n uint64) error {
|
||||
@ -57,7 +57,7 @@ func (e *Encoder) encodeUint64Cond(n uint64) error {
|
||||
|
||||
// EncodeInt8 encodes an int8 in 2 bytes preserving type of the number.
|
||||
func (e *Encoder) EncodeInt8(n int8) error {
|
||||
return e.write1(codes.Int8, uint8(n))
|
||||
return e.write1(msgpcode.Int8, uint8(n))
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeInt8Cond(n int8) error {
|
||||
@ -69,7 +69,7 @@ func (e *Encoder) encodeInt8Cond(n int8) error {
|
||||
|
||||
// EncodeInt16 encodes an int16 in 3 bytes preserving type of the number.
|
||||
func (e *Encoder) EncodeInt16(n int16) error {
|
||||
return e.write2(codes.Int16, uint16(n))
|
||||
return e.write2(msgpcode.Int16, uint16(n))
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeInt16Cond(n int16) error {
|
||||
@ -81,7 +81,7 @@ func (e *Encoder) encodeInt16Cond(n int16) error {
|
||||
|
||||
// EncodeInt32 encodes an int32 in 5 bytes preserving type of the number.
|
||||
func (e *Encoder) EncodeInt32(n int32) error {
|
||||
return e.write4(codes.Int32, uint32(n))
|
||||
return e.write4(msgpcode.Int32, uint32(n))
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeInt32Cond(n int32) error {
|
||||
@ -93,7 +93,7 @@ func (e *Encoder) encodeInt32Cond(n int32) error {
|
||||
|
||||
// EncodeInt64 encodes an int64 in 9 bytes preserving type of the number.
|
||||
func (e *Encoder) EncodeInt64(n int64) error {
|
||||
return e.write8(codes.Int64, uint64(n))
|
||||
return e.write8(msgpcode.Int64, uint64(n))
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeInt64Cond(n int64) error {
|
||||
@ -127,7 +127,7 @@ func (e *Encoder) EncodeInt(n int64) error {
|
||||
if n >= 0 {
|
||||
return e.EncodeUint(uint64(n))
|
||||
}
|
||||
if n >= int64(int8(codes.NegFixedNumLow)) {
|
||||
if n >= int64(int8(msgpcode.NegFixedNumLow)) {
|
||||
return e.w.WriteByte(byte(n))
|
||||
}
|
||||
if n >= math.MinInt8 {
|
||||
@ -148,7 +148,7 @@ func (e *Encoder) EncodeFloat32(n float32) error {
|
||||
return e.EncodeInt(int64(n))
|
||||
}
|
||||
}
|
||||
return e.write4(codes.Float, math.Float32bits(n))
|
||||
return e.write4(msgpcode.Float, math.Float32bits(n))
|
||||
}
|
||||
|
||||
func (e *Encoder) EncodeFloat64(n float64) error {
|
||||
@ -161,27 +161,27 @@ func (e *Encoder) EncodeFloat64(n float64) error {
|
||||
return e.EncodeInt(int64(n))
|
||||
}
|
||||
}
|
||||
return e.write8(codes.Double, math.Float64bits(n))
|
||||
return e.write8(msgpcode.Double, math.Float64bits(n))
|
||||
}
|
||||
|
||||
func (e *Encoder) write1(code codes.Code, n uint8) error {
|
||||
func (e *Encoder) write1(code byte, n uint8) error {
|
||||
e.buf = e.buf[:2]
|
||||
e.buf[0] = byte(code)
|
||||
e.buf[0] = code
|
||||
e.buf[1] = n
|
||||
return e.write(e.buf)
|
||||
}
|
||||
|
||||
func (e *Encoder) write2(code codes.Code, n uint16) error {
|
||||
func (e *Encoder) write2(code byte, n uint16) error {
|
||||
e.buf = e.buf[:3]
|
||||
e.buf[0] = byte(code)
|
||||
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 codes.Code, n uint32) error {
|
||||
func (e *Encoder) write4(code byte, n uint32) error {
|
||||
e.buf = e.buf[:5]
|
||||
e.buf[0] = byte(code)
|
||||
e.buf[0] = code
|
||||
e.buf[1] = byte(n >> 24)
|
||||
e.buf[2] = byte(n >> 16)
|
||||
e.buf[3] = byte(n >> 8)
|
||||
@ -189,9 +189,9 @@ func (e *Encoder) write4(code codes.Code, n uint32) error {
|
||||
return e.write(e.buf)
|
||||
}
|
||||
|
||||
func (e *Encoder) write8(code codes.Code, n uint64) error {
|
||||
func (e *Encoder) write8(code byte, n uint64) error {
|
||||
e.buf = e.buf[:9]
|
||||
e.buf[0] = byte(code)
|
||||
e.buf[0] = code
|
||||
e.buf[1] = byte(n >> 56)
|
||||
e.buf[2] = byte(n >> 48)
|
||||
e.buf[3] = byte(n >> 40)
|
||||
@ -203,6 +203,14 @@ func (e *Encoder) write8(code codes.Code, n uint64) error {
|
||||
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()))
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
package msgpack
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"github.com/vmihailenco/msgpack/v5/msgpcode"
|
||||
)
|
||||
|
||||
var sliceStringType = reflect.TypeOf(([]string)(nil))
|
||||
var stringSliceType = reflect.TypeOf(([]string)(nil))
|
||||
|
||||
func encodeStringValue(e *Encoder, v reflect.Value) error {
|
||||
return e.EncodeString(v.String())
|
||||
@ -42,29 +43,36 @@ func grow(b []byte, n int) []byte {
|
||||
|
||||
func (e *Encoder) EncodeBytesLen(l int) error {
|
||||
if l < 256 {
|
||||
return e.write1(codes.Bin8, uint8(l))
|
||||
return e.write1(msgpcode.Bin8, uint8(l))
|
||||
}
|
||||
if l < 65536 {
|
||||
return e.write2(codes.Bin16, uint16(l))
|
||||
if l <= math.MaxUint16 {
|
||||
return e.write2(msgpcode.Bin16, uint16(l))
|
||||
}
|
||||
return e.write4(codes.Bin32, uint32(l))
|
||||
return e.write4(msgpcode.Bin32, uint32(l))
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeStrLen(l int) error {
|
||||
func (e *Encoder) encodeStringLen(l int) error {
|
||||
if l < 32 {
|
||||
return e.writeCode(codes.FixedStrLow | codes.Code(l))
|
||||
return e.writeCode(msgpcode.FixedStrLow | byte(l))
|
||||
}
|
||||
if l < 256 {
|
||||
return e.write1(codes.Str8, uint8(l))
|
||||
return e.write1(msgpcode.Str8, uint8(l))
|
||||
}
|
||||
if l < 65536 {
|
||||
return e.write2(codes.Str16, uint16(l))
|
||||
if l <= math.MaxUint16 {
|
||||
return e.write2(msgpcode.Str16, uint16(l))
|
||||
}
|
||||
return e.write4(codes.Str32, uint32(l))
|
||||
return e.write4(msgpcode.Str32, uint32(l))
|
||||
}
|
||||
|
||||
func (e *Encoder) EncodeString(v string) error {
|
||||
if err := e.encodeStrLen(len(v)); err != nil {
|
||||
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)
|
||||
@ -82,16 +90,16 @@ func (e *Encoder) EncodeBytes(v []byte) error {
|
||||
|
||||
func (e *Encoder) EncodeArrayLen(l int) error {
|
||||
if l < 16 {
|
||||
return e.writeCode(codes.FixedArrayLow | codes.Code(l))
|
||||
return e.writeCode(msgpcode.FixedArrayLow | byte(l))
|
||||
}
|
||||
if l < 65536 {
|
||||
return e.write2(codes.Array16, uint16(l))
|
||||
if l <= math.MaxUint16 {
|
||||
return e.write2(msgpcode.Array16, uint16(l))
|
||||
}
|
||||
return e.write4(codes.Array32, uint32(l))
|
||||
return e.write4(msgpcode.Array32, uint32(l))
|
||||
}
|
||||
|
||||
func encodeStringSliceValue(e *Encoder, v reflect.Value) error {
|
||||
ss := v.Convert(sliceStringType).Interface().([]string)
|
||||
ss := v.Convert(stringSliceType).Interface().([]string)
|
||||
return e.encodeStringSlice(ss)
|
||||
}
|
||||
|
@ -12,12 +12,12 @@ var valueEncoders []encoderFunc
|
||||
func init() {
|
||||
valueEncoders = []encoderFunc{
|
||||
reflect.Bool: encodeBoolValue,
|
||||
reflect.Int: encodeInt64CondValue,
|
||||
reflect.Int: encodeIntValue,
|
||||
reflect.Int8: encodeInt8CondValue,
|
||||
reflect.Int16: encodeInt16CondValue,
|
||||
reflect.Int32: encodeInt32CondValue,
|
||||
reflect.Int64: encodeInt64CondValue,
|
||||
reflect.Uint: encodeUint64CondValue,
|
||||
reflect.Uint: encodeUintValue,
|
||||
reflect.Uint8: encodeUint8CondValue,
|
||||
reflect.Uint16: encodeUint16CondValue,
|
||||
reflect.Uint32: encodeUint32CondValue,
|
||||
@ -66,6 +66,9 @@ func _getEncoder(typ reflect.Type) encoderFunc {
|
||||
if typ.Implements(binaryMarshalerType) {
|
||||
return marshalBinaryValue
|
||||
}
|
||||
if typ.Implements(textMarshalerType) {
|
||||
return marshalTextValue
|
||||
}
|
||||
|
||||
// Addressable struct field value.
|
||||
if kind != reflect.Ptr {
|
||||
@ -77,7 +80,10 @@ func _getEncoder(typ reflect.Type) encoderFunc {
|
||||
return marshalValuePtr
|
||||
}
|
||||
if ptr.Implements(binaryMarshalerType) {
|
||||
return marshalBinaryValuePtr
|
||||
return marshalBinaryValueAddr
|
||||
}
|
||||
if ptr.Implements(textMarshalerType) {
|
||||
return marshalTextValueAddr
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,7 +139,7 @@ func encodeCustomValuePtr(e *Encoder, v reflect.Value) error {
|
||||
}
|
||||
|
||||
func encodeCustomValue(e *Encoder, v reflect.Value) error {
|
||||
if nilable(v) && v.IsNil() {
|
||||
if nilable(v.Kind()) && v.IsNil() {
|
||||
return e.EncodeNil()
|
||||
}
|
||||
|
||||
@ -149,7 +155,7 @@ func marshalValuePtr(e *Encoder, v reflect.Value) error {
|
||||
}
|
||||
|
||||
func marshalValue(e *Encoder, v reflect.Value) error {
|
||||
if nilable(v) && v.IsNil() {
|
||||
if nilable(v.Kind()) && v.IsNil() {
|
||||
return e.EncodeNil()
|
||||
}
|
||||
|
||||
@ -184,8 +190,8 @@ func encodeUnsupportedValue(e *Encoder, v reflect.Value) error {
|
||||
return fmt.Errorf("msgpack: Encode(unsupported %s)", v.Type())
|
||||
}
|
||||
|
||||
func nilable(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
func nilable(kind reflect.Kind) bool {
|
||||
switch kind {
|
||||
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
return true
|
||||
}
|
||||
@ -194,7 +200,7 @@ func nilable(v reflect.Value) bool {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
func marshalBinaryValuePtr(e *Encoder, v reflect.Value) error {
|
||||
func marshalBinaryValueAddr(e *Encoder, v reflect.Value) error {
|
||||
if !v.CanAddr() {
|
||||
return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
|
||||
}
|
||||
@ -202,7 +208,7 @@ func marshalBinaryValuePtr(e *Encoder, v reflect.Value) error {
|
||||
}
|
||||
|
||||
func marshalBinaryValue(e *Encoder, v reflect.Value) error {
|
||||
if nilable(v) && v.IsNil() {
|
||||
if nilable(v.Kind()) && v.IsNil() {
|
||||
return e.EncodeNil()
|
||||
}
|
||||
|
||||
@ -214,3 +220,26 @@ func marshalBinaryValue(e *Encoder, v reflect.Value) error {
|
||||
|
||||
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)
|
||||
}
|
303
vendor/github.com/vmihailenco/msgpack/v5/ext.go
generated
vendored
Normal file
303
vendor/github.com/vmihailenco/msgpack/v5/ext.go
generated
vendored
Normal file
@ -0,0 +1,303 @@
|
||||
package 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
|
||||
}
|
238
vendor/github.com/vmihailenco/msgpack/v5/intern.go
generated
vendored
Normal file
238
vendor/github.com/vmihailenco/msgpack/v5/intern.go
generated
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
package 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
|
||||
}
|
52
vendor/github.com/vmihailenco/msgpack/v5/msgpack.go
generated
vendored
Normal file
52
vendor/github.com/vmihailenco/msgpack/v5/msgpack.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
package 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)
|
||||
}
|
88
vendor/github.com/vmihailenco/msgpack/v5/msgpcode/msgpcode.go
generated
vendored
Normal file
88
vendor/github.com/vmihailenco/msgpack/v5/msgpcode/msgpcode.go
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
package 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
|
||||
}
|
4
vendor/github.com/vmihailenco/msgpack/v5/package.json
generated
vendored
Normal file
4
vendor/github.com/vmihailenco/msgpack/v5/package.json
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "msgpack",
|
||||
"version": "5.3.5"
|
||||
}
|
@ -6,16 +6,30 @@ import (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/vmihailenco/msgpack/v4/codes"
|
||||
"github.com/vmihailenco/msgpack/v5/msgpcode"
|
||||
)
|
||||
|
||||
var timeExtID int8 = -1
|
||||
|
||||
var timePtrType = reflect.TypeOf((*time.Time)(nil))
|
||||
|
||||
//nolint:gochecknoinits
|
||||
func init() {
|
||||
registerExt(timeExtID, timePtrType.Elem(), encodeTimeValue, decodeTimeValue)
|
||||
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 {
|
||||
@ -30,14 +44,20 @@ func (e *Encoder) EncodeTime(tm time.Time) error {
|
||||
}
|
||||
|
||||
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
|
||||
@ -50,62 +70,56 @@ func (e *Encoder) encodeTime(tm time.Time) []byte {
|
||||
}
|
||||
|
||||
func (d *Decoder) DecodeTime() (time.Time, error) {
|
||||
tm, err := d.decodeTime()
|
||||
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() {
|
||||
// Assume that zero time does not have timezone information.
|
||||
// Zero time does not have timezone information.
|
||||
return tm.UTC(), nil
|
||||
}
|
||||
return tm, nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeTime() (time.Time, error) {
|
||||
extLen := d.extLen
|
||||
d.extLen = 0
|
||||
if extLen == 0 {
|
||||
c, err := d.readCode()
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
|
||||
// Legacy format.
|
||||
if c == codes.FixedArrayLow|2 {
|
||||
sec, err := d.DecodeInt64()
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
|
||||
nsec, err := d.DecodeInt64()
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
|
||||
return time.Unix(sec, nsec), nil
|
||||
}
|
||||
|
||||
if codes.IsString(c) {
|
||||
s, err := d.string(c)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
return time.Parse(time.RFC3339Nano, s)
|
||||
}
|
||||
|
||||
extLen, err = d.parseExtLen(c)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
|
||||
// Skip ext id.
|
||||
_, err = d.s.ReadByte()
|
||||
if err != nil {
|
||||
return time.Time{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeTime(extLen int) (time.Time, error) {
|
||||
b, err := d.readN(extLen)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
@ -129,21 +143,3 @@ func (d *Decoder) decodeTime() (time.Time, error) {
|
||||
return time.Time{}, err
|
||||
}
|
||||
}
|
||||
|
||||
func encodeTimeValue(e *Encoder, v reflect.Value) error {
|
||||
tm := v.Interface().(time.Time)
|
||||
b := e.encodeTime(tm)
|
||||
return e.write(b)
|
||||
}
|
||||
|
||||
func decodeTimeValue(d *Decoder, v reflect.Value) error {
|
||||
tm, err := d.DecodeTime()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ptr := v.Addr().Interface().(*time.Time)
|
||||
*ptr = tm
|
||||
|
||||
return nil
|
||||
}
|
@ -7,7 +7,7 @@ import (
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/vmihailenco/tagparser"
|
||||
"github.com/vmihailenco/tagparser/v2"
|
||||
)
|
||||
|
||||
var errorType = reflect.TypeOf((*error)(nil)).Elem()
|
||||
@ -27,6 +27,11 @@ var (
|
||||
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
|
||||
@ -39,7 +44,7 @@ var (
|
||||
|
||||
// Register registers encoder and decoder functions for a value.
|
||||
// This is low level API and in most cases you should prefer implementing
|
||||
// Marshaler/CustomEncoder and Unmarshaler/CustomDecoder interfaces.
|
||||
// CustomEncoder/CustomDecoder or Marshaler/Unmarshaler interfaces.
|
||||
func Register(value interface{}, enc encoderFunc, dec decoderFunc) {
|
||||
typ := reflect.TypeOf(value)
|
||||
if enc != nil {
|
||||
@ -52,30 +57,33 @@ func Register(value interface{}, enc encoderFunc, dec decoderFunc) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
var (
|
||||
structs = newStructCache(false)
|
||||
jsonStructs = newStructCache(true)
|
||||
)
|
||||
const defaultStructTag = "msgpack"
|
||||
|
||||
var structs = newStructCache()
|
||||
|
||||
type structCache struct {
|
||||
m sync.Map
|
||||
|
||||
useJSONTag bool
|
||||
}
|
||||
|
||||
func newStructCache(useJSONTag bool) *structCache {
|
||||
return &structCache{
|
||||
useJSONTag: useJSONTag,
|
||||
}
|
||||
type structCacheKey struct {
|
||||
tag string
|
||||
typ reflect.Type
|
||||
}
|
||||
|
||||
func (m *structCache) Fields(typ reflect.Type) *fields {
|
||||
if v, ok := m.m.Load(typ); ok {
|
||||
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, m.useJSONTag)
|
||||
m.m.Store(typ, fs)
|
||||
fs := getFields(typ, tag)
|
||||
m.m.Store(key, fs)
|
||||
|
||||
return fs
|
||||
}
|
||||
|
||||
@ -89,17 +97,17 @@ type field struct {
|
||||
decoder decoderFunc
|
||||
}
|
||||
|
||||
func (f *field) Omit(strct reflect.Value) bool {
|
||||
v, isNil := fieldByIndex(strct, f.index)
|
||||
if isNil {
|
||||
func (f *field) Omit(strct reflect.Value, forced bool) bool {
|
||||
v, ok := fieldByIndex(strct, f.index)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
return f.omitEmpty && isEmptyValue(v)
|
||||
return (f.omitEmpty || forced) && isEmptyValue(v)
|
||||
}
|
||||
|
||||
func (f *field) EncodeValue(e *Encoder, strct reflect.Value) error {
|
||||
v, isNil := fieldByIndex(strct, f.index)
|
||||
if isNil {
|
||||
v, ok := fieldByIndex(strct, f.index)
|
||||
if !ok {
|
||||
return e.EncodeNil()
|
||||
}
|
||||
return f.encoder(e, v)
|
||||
@ -144,15 +152,15 @@ func (fs *fields) warnIfFieldExists(name string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *fields) OmitEmpty(strct reflect.Value) []*field {
|
||||
if !fs.hasOmitEmpty {
|
||||
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) {
|
||||
if !f.Omit(strct, forced) {
|
||||
fields = append(fields, f)
|
||||
}
|
||||
}
|
||||
@ -160,16 +168,16 @@ func (fs *fields) OmitEmpty(strct reflect.Value) []*field {
|
||||
return fields
|
||||
}
|
||||
|
||||
func getFields(typ reflect.Type, useJSONTag bool) *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("msgpack")
|
||||
if useJSONTag && tagStr == "" {
|
||||
tagStr = f.Tag.Get("json")
|
||||
tagStr := f.Tag.Get(defaultStructTag)
|
||||
if tagStr == "" && fallbackTag != "" {
|
||||
tagStr = f.Tag.Get(fallbackTag)
|
||||
}
|
||||
|
||||
tag := tagparser.Parse(tagStr)
|
||||
@ -178,9 +186,7 @@ func getFields(typ reflect.Type, useJSONTag bool) *fields {
|
||||
}
|
||||
|
||||
if f.Name == "_msgpack" {
|
||||
if tag.HasOption("asArray") {
|
||||
fs.AsArray = true
|
||||
}
|
||||
fs.AsArray = tag.HasOption("as_array") || tag.HasOption("asArray")
|
||||
if tag.HasOption("omitempty") {
|
||||
omitEmpty = true
|
||||
}
|
||||
@ -199,11 +205,11 @@ func getFields(typ reflect.Type, useJSONTag bool) *fields {
|
||||
if tag.HasOption("intern") {
|
||||
switch f.Type.Kind() {
|
||||
case reflect.Interface:
|
||||
field.encoder = encodeInternInterfaceValue
|
||||
field.decoder = decodeInternInterfaceValue
|
||||
field.encoder = encodeInternedInterfaceValue
|
||||
field.decoder = decodeInternedInterfaceValue
|
||||
case reflect.String:
|
||||
field.encoder = encodeInternStringValue
|
||||
field.decoder = decodeInternStringValue
|
||||
field.encoder = encodeInternedStringValue
|
||||
field.decoder = decodeInternedStringValue
|
||||
default:
|
||||
err := fmt.Errorf("msgpack: intern strings are not supported on %s", f.Type)
|
||||
panic(err)
|
||||
@ -220,9 +226,9 @@ func getFields(typ reflect.Type, useJSONTag bool) *fields {
|
||||
if f.Anonymous && !tag.HasOption("noinline") {
|
||||
inline := tag.HasOption("inline")
|
||||
if inline {
|
||||
inlineFields(fs, f.Type, field, useJSONTag)
|
||||
inlineFields(fs, f.Type, field, fallbackTag)
|
||||
} else {
|
||||
inline = shouldInline(fs, f.Type, field, useJSONTag)
|
||||
inline = shouldInline(fs, f.Type, field, fallbackTag)
|
||||
}
|
||||
|
||||
if inline {
|
||||
@ -255,8 +261,8 @@ func init() {
|
||||
decodeStructValuePtr = reflect.ValueOf(decodeStructValue).Pointer()
|
||||
}
|
||||
|
||||
func inlineFields(fs *fields, typ reflect.Type, f *field, useJSONTag bool) {
|
||||
inlinedFields := getFields(typ, useJSONTag).List
|
||||
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.
|
||||
@ -267,7 +273,7 @@ func inlineFields(fs *fields, typ reflect.Type, f *field, useJSONTag bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func shouldInline(fs *fields, typ reflect.Type, f *field, useJSONTag bool) bool {
|
||||
func shouldInline(fs *fields, typ reflect.Type, f *field, tag string) bool {
|
||||
var encoder encoderFunc
|
||||
var decoder decoderFunc
|
||||
|
||||
@ -292,7 +298,7 @@ func shouldInline(fs *fields, typ reflect.Type, f *field, useJSONTag bool) bool
|
||||
return false
|
||||
}
|
||||
|
||||
inlinedFields := getFields(typ, useJSONTag).List
|
||||
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.
|
||||
@ -307,8 +313,26 @@ func shouldInline(fs *fields, typ reflect.Type, f *field, useJSONTag bool) bool
|
||||
return true
|
||||
}
|
||||
|
||||
type isZeroer interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
||||
func isEmptyValue(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
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:
|
||||
@ -319,22 +343,23 @@ func isEmptyValue(v reflect.Value) bool {
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
case reflect.Ptr:
|
||||
return v.IsNil()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func fieldByIndex(v reflect.Value, index []int) (_ reflect.Value, isNil bool) {
|
||||
func fieldByIndex(v reflect.Value, index []int) (_ reflect.Value, ok bool) {
|
||||
if len(index) == 1 {
|
||||
return v.Field(index[0]), false
|
||||
return v.Field(index[0]), true
|
||||
}
|
||||
|
||||
for i, idx := range index {
|
||||
if i > 0 {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return v, true
|
||||
return v, false
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
@ -342,7 +367,7 @@ func fieldByIndex(v reflect.Value, index []int) (_ reflect.Value, isNil bool) {
|
||||
v = v.Field(idx)
|
||||
}
|
||||
|
||||
return v, false
|
||||
return v, true
|
||||
}
|
||||
|
||||
func fieldByIndexAlloc(v reflect.Value, index []int) reflect.Value {
|
||||
@ -353,7 +378,7 @@ func fieldByIndexAlloc(v reflect.Value, index []int) reflect.Value {
|
||||
for i, idx := range index {
|
||||
if i > 0 {
|
||||
var ok bool
|
||||
v, ok = indirectNew(v)
|
||||
v, ok = indirectNil(v)
|
||||
if !ok {
|
||||
return v
|
||||
}
|
||||
@ -364,7 +389,7 @@ func fieldByIndexAlloc(v reflect.Value, index []int) reflect.Value {
|
||||
return v
|
||||
}
|
||||
|
||||
func indirectNew(v reflect.Value) (reflect.Value, bool) {
|
||||
func indirectNil(v reflect.Value) (reflect.Value, bool) {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
if !v.CanSet() {
|
@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
// bytesToString converts byte slice to string.
|
||||
func bytesToString(b []byte) string { //nolint:deadcode,unused
|
||||
func bytesToString(b []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&b))
|
||||
}
|
||||
|
6
vendor/github.com/vmihailenco/msgpack/v5/version.go
generated
vendored
Normal file
6
vendor/github.com/vmihailenco/msgpack/v5/version.go
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
package msgpack
|
||||
|
||||
// Version is the current release version.
|
||||
func Version() string {
|
||||
return "5.3.5"
|
||||
}
|
Reference in New Issue
Block a user