package msgpack
import (
)
const (
looseInterfaceDecodingFlag uint32 = 1 << iota
disallowUnknownFieldsFlag
)
const (
bytesAllocLimit = 1e6
sliceAllocLimit = 1e4
maxMapSize = 1e6
)
type bufReader interface {
io.Reader
io.ByteScanner
}
var decPool = sync.Pool{
New: func() interface{} {
return NewDecoder(nil)
},
}
func () *Decoder {
return decPool.Get().(*Decoder)
}
func ( *Decoder) {
.r = nil
.s = nil
decPool.Put()
}
func ( []byte, interface{}) error {
:= GetDecoder()
.Reset(bytes.NewReader())
:= .Decode()
PutDecoder()
return
}
type Decoder struct {
r io.Reader
s io.ByteScanner
buf []byte
rec []byte
dict []string
flags uint32
structTag string
mapDecoder func(*Decoder) (interface{}, error)
}
func ( io.Reader) *Decoder {
:= new(Decoder)
.Reset()
return
}
func ( *Decoder) ( io.Reader) {
.ResetDict(, nil)
}
func ( *Decoder) ( io.Reader, []string) {
.resetReader()
.flags = 0
.structTag = ""
.mapDecoder = nil
.dict =
}
func ( *Decoder) ( []string, func(*Decoder) error) error {
:= .dict
.dict =
:= ()
.dict =
return
}
func ( *Decoder) ( io.Reader) {
if , := .(bufReader); {
.r =
.s =
} else {
:= bufio.NewReader()
.r =
.s =
}
}
func ( *Decoder) ( func(*Decoder) (interface{}, error)) {
.mapDecoder =
}
func ( *Decoder) ( bool) {
if {
.flags |= looseInterfaceDecodingFlag
} else {
.flags &= ^looseInterfaceDecodingFlag
}
}
func ( *Decoder) ( string) {
.structTag =
}
func ( *Decoder) ( bool) {
if {
.flags |= disallowUnknownFieldsFlag
} else {
.flags &= ^disallowUnknownFieldsFlag
}
}
func ( *Decoder) ( bool) {
if {
.flags |= useInternedStringsFlag
} else {
.flags &= ^useInternedStringsFlag
}
}
func ( *Decoder) () io.Reader {
return .r
}
func ( *Decoder) ( interface{}) error {
var error
switch v := .(type) {
case *string:
if != nil {
*, = .DecodeString()
return
}
case *[]byte:
if != nil {
return .decodeBytesPtr()
}
case *int:
if != nil {
*, = .DecodeInt()
return
}
case *int8:
if != nil {
*, = .DecodeInt8()
return
}
case *int16:
if != nil {
*, = .DecodeInt16()
return
}
case *int32:
if != nil {
*, = .DecodeInt32()
return
}
case *int64:
if != nil {
*, = .DecodeInt64()
return
}
case *uint:
if != nil {
*, = .DecodeUint()
return
}
case *uint8:
if != nil {
*, = .DecodeUint8()
return
}
case *uint16:
if != nil {
*, = .DecodeUint16()
return
}
case *uint32:
if != nil {
*, = .DecodeUint32()
return
}
case *uint64:
if != nil {
*, = .DecodeUint64()
return
}
case *bool:
if != nil {
*, = .DecodeBool()
return
}
case *float32:
if != nil {
*, = .DecodeFloat32()
return
}
case *float64:
if != nil {
*, = .DecodeFloat64()
return
}
case *[]string:
return .decodeStringSlicePtr()
case *map[string]string:
return .decodeMapStringStringPtr()
case *map[string]interface{}:
return .decodeMapStringInterfacePtr()
case *time.Duration:
if != nil {
, := .DecodeInt64()
* = time.Duration()
return
}
case *time.Time:
if != nil {
*, = .DecodeTime()
return
}
}
:= reflect.ValueOf()
if !.IsValid() {
return errors.New("msgpack: Decode(nil)")
}
if .Kind() != reflect.Ptr {
return fmt.Errorf("msgpack: Decode(non-pointer %T)", )
}
if .IsNil() {
return fmt.Errorf("msgpack: Decode(non-settable %T)", )
}
= .Elem()
if .Kind() == reflect.Interface {
if !.IsNil() {
= .Elem()
if .Kind() != reflect.Ptr {
return fmt.Errorf("msgpack: Decode(non-pointer %s)", .Type().String())
}
}
}
return .DecodeValue()
}
func ( *Decoder) ( ...interface{}) error {
for , := range {
if := .Decode(); != nil {
return
}
}
return nil
}
func ( *Decoder) () (interface{}, error) {
if .flags&looseInterfaceDecodingFlag != 0 {
return .DecodeInterfaceLoose()
}
return .DecodeInterface()
}
func ( *Decoder) ( reflect.Value) error {
:= getDecoder(.Type())
return (, )
}
func ( *Decoder) () error {
, := .readCode()
if != nil {
return
}
if != msgpcode.Nil {
return fmt.Errorf("msgpack: invalid code=%x decoding nil", )
}
return nil
}
func ( *Decoder) ( reflect.Value) error {
:= .DecodeNil()
if .IsNil() {
return
}
if .Kind() == reflect.Ptr {
= .Elem()
}
.Set(reflect.Zero(.Type()))
return
}
func ( *Decoder) () (bool, error) {
, := .readCode()
if != nil {
return false,
}
return .bool()
}
func ( *Decoder) ( byte) (bool, error) {
if == msgpcode.Nil {
return false, nil
}
if == msgpcode.False {
return false, nil
}
if == msgpcode.True {
return true, nil
}
return false, fmt.Errorf("msgpack: invalid code=%x decoding bool", )
}
func ( *Decoder) () (time.Duration, error) {
, := .DecodeInt64()
if != nil {
return 0,
}
return time.Duration(), nil
}
func ( *Decoder) () (interface{}, error) {
, := .readCode()
if != nil {
return nil,
}
if msgpcode.IsFixedNum() {
return int8(), nil
}
if msgpcode.IsFixedMap() {
= .s.UnreadByte()
if != nil {
return nil,
}
return .decodeMapDefault()
}
if msgpcode.IsFixedArray() {
return .decodeSlice()
}
if msgpcode.IsFixedString() {
return .string()
}
switch {
case msgpcode.Nil:
return nil, nil
case msgpcode.False, msgpcode.True:
return .bool()
case msgpcode.Float:
return .float32()
case msgpcode.Double:
return .float64()
case msgpcode.Uint8:
return .uint8()
case msgpcode.Uint16:
return .uint16()
case msgpcode.Uint32:
return .uint32()
case msgpcode.Uint64:
return .uint64()
case msgpcode.Int8:
return .int8()
case msgpcode.Int16:
return .int16()
case msgpcode.Int32:
return .int32()
case msgpcode.Int64:
return .int64()
case msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32:
return .bytes(, nil)
case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32:
return .string()
case msgpcode.Array16, msgpcode.Array32:
return .decodeSlice()
case msgpcode.Map16, msgpcode.Map32:
= .s.UnreadByte()
if != nil {
return nil,
}
return .decodeMapDefault()
case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4, msgpcode.FixExt8, msgpcode.FixExt16,
msgpcode.Ext8, msgpcode.Ext16, msgpcode.Ext32:
return .decodeInterfaceExt()
}
return 0, fmt.Errorf("msgpack: unknown code %x decoding interface{}", )
}
func ( *Decoder) () (interface{}, error) {
, := .readCode()
if != nil {
return nil,
}
if msgpcode.IsFixedNum() {
return int64(int8()), nil
}
if msgpcode.IsFixedMap() {
= .s.UnreadByte()
if != nil {
return nil,
}
return .decodeMapDefault()
}
if msgpcode.IsFixedArray() {
return .decodeSlice()
}
if msgpcode.IsFixedString() {
return .string()
}
switch {
case msgpcode.Nil:
return nil, nil
case msgpcode.False, msgpcode.True:
return .bool()
case msgpcode.Float, msgpcode.Double:
return .float64()
case msgpcode.Uint8, msgpcode.Uint16, msgpcode.Uint32, msgpcode.Uint64:
return .uint()
case msgpcode.Int8, msgpcode.Int16, msgpcode.Int32, msgpcode.Int64:
return .int()
case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32,
msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32:
return .string()
case msgpcode.Array16, msgpcode.Array32:
return .decodeSlice()
case msgpcode.Map16, msgpcode.Map32:
= .s.UnreadByte()
if != nil {
return nil,
}
return .decodeMapDefault()
case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4, msgpcode.FixExt8, msgpcode.FixExt16,
msgpcode.Ext8, msgpcode.Ext16, msgpcode.Ext32:
return .decodeInterfaceExt()
}
return 0, fmt.Errorf("msgpack: unknown code %x decoding interface{}", )
}
func ( *Decoder) () error {
, := .readCode()
if != nil {
return
}
if msgpcode.IsFixedNum() {
return nil
}
if msgpcode.IsFixedMap() {
return .skipMap()
}
if msgpcode.IsFixedArray() {
return .skipSlice()
}
if msgpcode.IsFixedString() {
return .skipBytes()
}
switch {
case msgpcode.Nil, msgpcode.False, msgpcode.True:
return nil
case msgpcode.Uint8, msgpcode.Int8:
return .skipN(1)
case msgpcode.Uint16, msgpcode.Int16:
return .skipN(2)
case msgpcode.Uint32, msgpcode.Int32, msgpcode.Float:
return .skipN(4)
case msgpcode.Uint64, msgpcode.Int64, msgpcode.Double:
return .skipN(8)
case msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32:
return .skipBytes()
case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32:
return .skipBytes()
case msgpcode.Array16, msgpcode.Array32:
return .skipSlice()
case msgpcode.Map16, msgpcode.Map32:
return .skipMap()
case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4, msgpcode.FixExt8, msgpcode.FixExt16,
msgpcode.Ext8, msgpcode.Ext16, msgpcode.Ext32:
return .skipExt()
}
return fmt.Errorf("msgpack: unknown code %x", )
}
func ( *Decoder) () (RawMessage, error) {
.rec = make([]byte, 0)
if := .Skip(); != nil {
return nil,
}
:= RawMessage(.rec)
.rec = nil
return , nil
}
func ( *Decoder) () (byte, error) {
, := .s.ReadByte()
if != nil {
return 0,
}
return , .s.UnreadByte()
}
func ( *Decoder) ( []byte) error {
, := readN(.r, , len())
return
}
func ( *Decoder) () bool {
, := .PeekCode()
return == nil && == msgpcode.Nil
}
func ( *Decoder) () (byte, error) {
, := .s.ReadByte()
if != nil {
return 0,
}
if .rec != nil {
.rec = append(.rec, )
}
return , nil
}
func ( *Decoder) ( []byte) error {
, := io.ReadFull(.r, )
if != nil {
return
}
if .rec != nil {
.rec = append(.rec, ...)
}
return nil
}
func ( *Decoder) ( int) ([]byte, error) {
var error
.buf, = readN(.r, .buf, )
if != nil {
return nil,
}
if .rec != nil {
.rec = append(.rec, .buf...)
}
return .buf, nil
}
func ( io.Reader, []byte, int) ([]byte, error) {
if == nil {
if == 0 {
return make([]byte, 0), nil
}
switch {
case < 64:
= make([]byte, 0, 64)
case <= bytesAllocLimit:
= make([]byte, 0, )
default:
= make([]byte, 0, bytesAllocLimit)
}
}
if <= cap() {
= [:]
, := io.ReadFull(, )
return ,
}
= [:cap()]
var int
for {
:= min(-len(), bytesAllocLimit)
= append(, make([]byte, )...)
, := io.ReadFull(, [:])
if != nil {
return ,
}
if len() == {
break
}
= len()
}
return , nil
}
func (, int) int {
if <= {
return
}
return
}