Browse Source

Merge pull request #10667 from dims/replace-ugorji-with-json-iterator

Replace ugorji/codec with json-iterator/go
Gyuho Lee 6 years ago
parent
commit
1697c06df9
100 changed files with 11318 additions and 12052 deletions
  1. 27 9
      bill-of-materials.json
  2. 72 0
      client/json.go
  3. 0 4516
      client/keys.generated.go
  4. 4 6
      client/keys.go
  5. 3 1
      go.mod
  6. 6 4
      go.sum
  7. 0 18
      scripts/update-clientv2.sh
  8. 0 90
      vendor/github.com/coreos/go-systemd/util/util.go
  9. 0 175
      vendor/github.com/coreos/go-systemd/util/util_cgo.go
  10. 0 23
      vendor/github.com/coreos/go-systemd/util/util_stub.go
  11. 0 82
      vendor/github.com/coreos/pkg/dlopen/dlopen.go
  12. 0 56
      vendor/github.com/coreos/pkg/dlopen/dlopen_example.go
  13. 2 3
      vendor/github.com/json-iterator/go/LICENSE
  14. 150 0
      vendor/github.com/json-iterator/go/adapter.go
  15. 321 0
      vendor/github.com/json-iterator/go/any.go
  16. 278 0
      vendor/github.com/json-iterator/go/any_array.go
  17. 137 0
      vendor/github.com/json-iterator/go/any_bool.go
  18. 83 0
      vendor/github.com/json-iterator/go/any_float.go
  19. 74 0
      vendor/github.com/json-iterator/go/any_int32.go
  20. 74 0
      vendor/github.com/json-iterator/go/any_int64.go
  21. 82 0
      vendor/github.com/json-iterator/go/any_invalid.go
  22. 69 0
      vendor/github.com/json-iterator/go/any_nil.go
  23. 123 0
      vendor/github.com/json-iterator/go/any_number.go
  24. 374 0
      vendor/github.com/json-iterator/go/any_object.go
  25. 166 0
      vendor/github.com/json-iterator/go/any_str.go
  26. 74 0
      vendor/github.com/json-iterator/go/any_uint32.go
  27. 74 0
      vendor/github.com/json-iterator/go/any_uint64.go
  28. 375 0
      vendor/github.com/json-iterator/go/config.go
  29. 322 0
      vendor/github.com/json-iterator/go/iter.go
  30. 58 0
      vendor/github.com/json-iterator/go/iter_array.go
  31. 347 0
      vendor/github.com/json-iterator/go/iter_float.go
  32. 345 0
      vendor/github.com/json-iterator/go/iter_int.go
  33. 251 0
      vendor/github.com/json-iterator/go/iter_object.go
  34. 129 0
      vendor/github.com/json-iterator/go/iter_skip.go
  35. 144 0
      vendor/github.com/json-iterator/go/iter_skip_sloppy.go
  36. 89 0
      vendor/github.com/json-iterator/go/iter_skip_strict.go
  37. 215 0
      vendor/github.com/json-iterator/go/iter_str.go
  38. 18 0
      vendor/github.com/json-iterator/go/jsoniter.go
  39. 42 0
      vendor/github.com/json-iterator/go/pool.go
  40. 332 0
      vendor/github.com/json-iterator/go/reflect.go
  41. 104 0
      vendor/github.com/json-iterator/go/reflect_array.go
  42. 70 0
      vendor/github.com/json-iterator/go/reflect_dynamic.go
  43. 483 0
      vendor/github.com/json-iterator/go/reflect_extension.go
  44. 112 0
      vendor/github.com/json-iterator/go/reflect_json_number.go
  45. 60 0
      vendor/github.com/json-iterator/go/reflect_json_raw_message.go
  46. 326 0
      vendor/github.com/json-iterator/go/reflect_map.go
  47. 218 0
      vendor/github.com/json-iterator/go/reflect_marshaler.go
  48. 451 0
      vendor/github.com/json-iterator/go/reflect_native.go
  49. 133 0
      vendor/github.com/json-iterator/go/reflect_optional.go
  50. 99 0
      vendor/github.com/json-iterator/go/reflect_slice.go
  51. 1048 0
      vendor/github.com/json-iterator/go/reflect_struct_decoder.go
  52. 210 0
      vendor/github.com/json-iterator/go/reflect_struct_encoder.go
  53. 211 0
      vendor/github.com/json-iterator/go/stream.go
  54. 94 0
      vendor/github.com/json-iterator/go/stream_float.go
  55. 190 0
      vendor/github.com/json-iterator/go/stream_int.go
  56. 372 0
      vendor/github.com/json-iterator/go/stream_str.go
  57. 201 0
      vendor/github.com/modern-go/concurrent/LICENSE
  58. 14 0
      vendor/github.com/modern-go/concurrent/executor.go
  59. 15 0
      vendor/github.com/modern-go/concurrent/go_above_19.go
  60. 33 0
      vendor/github.com/modern-go/concurrent/go_below_19.go
  61. 13 0
      vendor/github.com/modern-go/concurrent/log.go
  62. 119 0
      vendor/github.com/modern-go/concurrent/unbounded_executor.go
  63. 201 0
      vendor/github.com/modern-go/reflect2/LICENSE
  64. 8 0
      vendor/github.com/modern-go/reflect2/go_above_17.go
  65. 14 0
      vendor/github.com/modern-go/reflect2/go_above_19.go
  66. 9 0
      vendor/github.com/modern-go/reflect2/go_below_17.go
  67. 14 0
      vendor/github.com/modern-go/reflect2/go_below_19.go
  68. 298 0
      vendor/github.com/modern-go/reflect2/reflect2.go
  69. 0 0
      vendor/github.com/modern-go/reflect2/reflect2_amd64.s
  70. 30 0
      vendor/github.com/modern-go/reflect2/reflect2_kind.go
  71. 0 0
      vendor/github.com/modern-go/reflect2/relfect2_386.s
  72. 0 0
      vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s
  73. 0 0
      vendor/github.com/modern-go/reflect2/relfect2_arm.s
  74. 0 0
      vendor/github.com/modern-go/reflect2/relfect2_arm64.s
  75. 0 0
      vendor/github.com/modern-go/reflect2/relfect2_mips64x.s
  76. 0 0
      vendor/github.com/modern-go/reflect2/relfect2_mipsx.s
  77. 0 0
      vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s
  78. 0 0
      vendor/github.com/modern-go/reflect2/relfect2_s390x.s
  79. 58 0
      vendor/github.com/modern-go/reflect2/safe_field.go
  80. 101 0
      vendor/github.com/modern-go/reflect2/safe_map.go
  81. 92 0
      vendor/github.com/modern-go/reflect2/safe_slice.go
  82. 29 0
      vendor/github.com/modern-go/reflect2/safe_struct.go
  83. 78 0
      vendor/github.com/modern-go/reflect2/safe_type.go
  84. 113 0
      vendor/github.com/modern-go/reflect2/type_map.go
  85. 65 0
      vendor/github.com/modern-go/reflect2/unsafe_array.go
  86. 59 0
      vendor/github.com/modern-go/reflect2/unsafe_eface.go
  87. 74 0
      vendor/github.com/modern-go/reflect2/unsafe_field.go
  88. 64 0
      vendor/github.com/modern-go/reflect2/unsafe_iface.go
  89. 70 0
      vendor/github.com/modern-go/reflect2/unsafe_link.go
  90. 138 0
      vendor/github.com/modern-go/reflect2/unsafe_map.go
  91. 46 0
      vendor/github.com/modern-go/reflect2/unsafe_ptr.go
  92. 177 0
      vendor/github.com/modern-go/reflect2/unsafe_slice.go
  93. 59 0
      vendor/github.com/modern-go/reflect2/unsafe_struct.go
  94. 85 0
      vendor/github.com/modern-go/reflect2/unsafe_type.go
  95. 0 227
      vendor/github.com/ugorji/go/codec/0doc.go
  96. 0 1204
      vendor/github.com/ugorji/go/codec/binc.go
  97. 0 769
      vendor/github.com/ugorji/go/codec/cbor.go
  98. 0 13
      vendor/github.com/ugorji/go/codec/codecgen.go
  99. 0 3095
      vendor/github.com/ugorji/go/codec/decode.go
  100. 0 1761
      vendor/github.com/ugorji/go/codec/encode.go

+ 27 - 9
bill-of-materials.json

@@ -170,6 +170,15 @@
 			}
 		]
 	},
+	{
+		"project": "github.com/json-iterator/go",
+		"licenses": [
+			{
+				"type": "MIT License",
+				"confidence": 1
+			}
+		]
+	},
 	{
 		"project": "github.com/mattn/go-runewidth",
 		"licenses": [
@@ -188,6 +197,24 @@
 			}
 		]
 	},
+	{
+		"project": "github.com/modern-go/concurrent",
+		"licenses": [
+			{
+				"type": "Apache License 2.0",
+				"confidence": 1
+			}
+		]
+	},
+	{
+		"project": "github.com/modern-go/reflect2",
+		"licenses": [
+			{
+				"type": "Apache License 2.0",
+				"confidence": 1
+			}
+		]
+	},
 	{
 		"project": "github.com/olekukonko/tablewriter",
 		"licenses": [
@@ -278,15 +305,6 @@
 			}
 		]
 	},
-	{
-		"project": "github.com/ugorji/go/codec",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.9946524064171123
-			}
-		]
-	},
 	{
 		"project": "github.com/urfave/cli",
 		"licenses": [

+ 72 - 0
client/json.go

@@ -0,0 +1,72 @@
+// Copyright 2019 The etcd Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package client
+
+import (
+	"github.com/json-iterator/go"
+	"github.com/modern-go/reflect2"
+	"strconv"
+	"unsafe"
+)
+
+type customNumberExtension struct {
+	jsoniter.DummyExtension
+}
+
+func (cne *customNumberExtension) CreateDecoder(typ reflect2.Type) jsoniter.ValDecoder {
+	if typ.String() == "interface {}" {
+		return customNumberDecoder{}
+	}
+	return nil
+}
+
+type customNumberDecoder struct {
+}
+
+func (customNumberDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+	switch iter.WhatIsNext() {
+	case jsoniter.NumberValue:
+		var number jsoniter.Number
+		iter.ReadVal(&number)
+		i64, err := strconv.ParseInt(string(number), 10, 64)
+		if err == nil {
+			*(*interface{})(ptr) = i64
+			return
+		}
+		f64, err := strconv.ParseFloat(string(number), 64)
+		if err == nil {
+			*(*interface{})(ptr) = f64
+			return
+		}
+		iter.ReportError("DecodeNumber", err.Error())
+	default:
+		*(*interface{})(ptr) = iter.Read()
+	}
+}
+
+// caseSensitiveJsonIterator returns a jsoniterator API that's configured to be
+// case-sensitive when unmarshalling, and otherwise compatible with
+// the encoding/json standard library.
+func caseSensitiveJsonIterator() jsoniter.API {
+	config := jsoniter.Config{
+		EscapeHTML:             true,
+		SortMapKeys:            true,
+		ValidateJsonRawMessage: true,
+		CaseSensitive:          true,
+	}.Froze()
+	// Force jsoniter to decode number to interface{} via int64/float64, if possible.
+	config.RegisterExtension(&customNumberExtension{})
+	return config
+}

+ 0 - 4516
client/keys.generated.go

@@ -1,4516 +0,0 @@
-// Code generated by codecgen - DO NOT EDIT.
-
-package client
-
-import (
-	"errors"
-	"runtime"
-	"strconv"
-	"time"
-
-	codec1978 "github.com/ugorji/go/codec"
-)
-
-const (
-	// ----- content types ----
-	codecSelferCcUTF89381 = 1
-	codecSelferCcRAW9381  = 255
-	// ----- value types used ----
-	codecSelferValueTypeArray9381  = 10
-	codecSelferValueTypeMap9381    = 9
-	codecSelferValueTypeString9381 = 6
-	codecSelferValueTypeInt9381    = 2
-	codecSelferValueTypeUint9381   = 3
-	codecSelferValueTypeFloat9381  = 4
-	codecSelferBitsize9381         = uint8(32 << (^uint(0) >> 63))
-)
-
-var (
-	errCodecSelferOnlyMapOrArrayEncodeToStruct9381 = errors.New(`only encoded map or array can be decoded into a struct`)
-)
-
-type codecSelfer9381 struct{}
-
-func init() {
-	if codec1978.GenVersion != 10 {
-		_, file, _, _ := runtime.Caller(0)
-		panic("codecgen version mismatch: current: 10, need " + strconv.FormatInt(int64(codec1978.GenVersion), 10) + ". Re-generate file: " + file)
-	}
-	if false {
-		var _ byte = 0 // reference the types, but skip this branch at build/run time
-		var v0 time.Duration
-		_ = v0
-	}
-}
-
-func (x *Error) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(4)
-			} else {
-				r.WriteMapStart(4)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeInt(int64(x.Code))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"errorCode\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `errorCode`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeInt(int64(x.Code))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Message))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"message\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `message`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Message))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Cause))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"cause\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `cause`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Cause))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.Index))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"index\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `index`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.Index))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *Error) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *Error) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "errorCode":
-			if r.TryDecodeAsNil() {
-				x.Code = 0
-			} else {
-				x.Code = (int)(z.C.IntV(r.DecodeInt64(), codecSelferBitsize9381))
-			}
-		case "message":
-			if r.TryDecodeAsNil() {
-				x.Message = ""
-			} else {
-				x.Message = (string)(r.DecodeString())
-			}
-		case "cause":
-			if r.TryDecodeAsNil() {
-				x.Cause = ""
-			} else {
-				x.Cause = (string)(r.DecodeString())
-			}
-		case "index":
-			if r.TryDecodeAsNil() {
-				x.Index = 0
-			} else {
-				x.Index = (uint64)(r.DecodeUint64())
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *Error) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj8 int
-	var yyb8 bool
-	var yyhl8 bool = l >= 0
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Code = 0
-	} else {
-		x.Code = (int)(z.C.IntV(r.DecodeInt64(), codecSelferBitsize9381))
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Message = ""
-	} else {
-		x.Message = (string)(r.DecodeString())
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Cause = ""
-	} else {
-		x.Cause = (string)(r.DecodeString())
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Index = 0
-	} else {
-		x.Index = (uint64)(r.DecodeUint64())
-	}
-	for {
-		yyj8++
-		if yyhl8 {
-			yyb8 = yyj8 > l
-		} else {
-			yyb8 = r.CheckBreak()
-		}
-		if yyb8 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj8-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x PrevExistType) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.EncExtension(x, yyxt1)
-	} else {
-		r.EncodeStringEnc(codecSelferCcUTF89381, string(x))
-	}
-}
-
-func (x *PrevExistType) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		*x = (PrevExistType)(r.DecodeString())
-	}
-}
-
-func (x *WatcherOptions) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(2)
-			} else {
-				r.WriteMapStart(2)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.AfterIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"AfterIndex\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `AfterIndex`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.AfterIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Recursive\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Recursive`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *WatcherOptions) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *WatcherOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "AfterIndex":
-			if r.TryDecodeAsNil() {
-				x.AfterIndex = 0
-			} else {
-				x.AfterIndex = (uint64)(r.DecodeUint64())
-			}
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				x.Recursive = (bool)(r.DecodeBool())
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *WatcherOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj6 int
-	var yyb6 bool
-	var yyhl6 bool = l >= 0
-	yyj6++
-	if yyhl6 {
-		yyb6 = yyj6 > l
-	} else {
-		yyb6 = r.CheckBreak()
-	}
-	if yyb6 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.AfterIndex = 0
-	} else {
-		x.AfterIndex = (uint64)(r.DecodeUint64())
-	}
-	yyj6++
-	if yyhl6 {
-		yyb6 = yyj6 > l
-	} else {
-		yyb6 = r.CheckBreak()
-	}
-	if yyb6 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		x.Recursive = (bool)(r.DecodeBool())
-	}
-	for {
-		yyj6++
-		if yyhl6 {
-			yyb6 = yyj6 > l
-		} else {
-			yyb6 = r.CheckBreak()
-		}
-		if yyb6 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj6-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *CreateInOrderOptions) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(1)
-			} else {
-				r.WriteMapStart(1)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else if yyxt4 := z.Extension(z.I2Rtid(x.TTL)); yyxt4 != nil {
-					z.EncExtension(x.TTL, yyxt4)
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"TTL\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `TTL`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else if yyxt5 := z.Extension(z.I2Rtid(x.TTL)); yyxt5 != nil {
-					z.EncExtension(x.TTL, yyxt5)
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *CreateInOrderOptions) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *CreateInOrderOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "TTL":
-			if r.TryDecodeAsNil() {
-				x.TTL = 0
-			} else {
-				if false {
-				} else if yyxt5 := z.Extension(z.I2Rtid(x.TTL)); yyxt5 != nil {
-					z.DecExtension(x.TTL, yyxt5)
-				} else {
-					x.TTL = (time.Duration)(r.DecodeInt64())
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *CreateInOrderOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj6 int
-	var yyb6 bool
-	var yyhl6 bool = l >= 0
-	yyj6++
-	if yyhl6 {
-		yyb6 = yyj6 > l
-	} else {
-		yyb6 = r.CheckBreak()
-	}
-	if yyb6 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.TTL = 0
-	} else {
-		if false {
-		} else if yyxt8 := z.Extension(z.I2Rtid(x.TTL)); yyxt8 != nil {
-			z.DecExtension(x.TTL, yyxt8)
-		} else {
-			x.TTL = (time.Duration)(r.DecodeInt64())
-		}
-	}
-	for {
-		yyj6++
-		if yyhl6 {
-			yyb6 = yyj6 > l
-		} else {
-			yyb6 = r.CheckBreak()
-		}
-		if yyb6 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj6-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *SetOptions) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(7)
-			} else {
-				r.WriteMapStart(7)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.PrevValue))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"PrevValue\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `PrevValue`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.PrevValue))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"PrevIndex\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `PrevIndex`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				x.PrevExist.CodecEncodeSelf(e)
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"PrevExist\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `PrevExist`)
-				}
-				r.WriteMapElemValue()
-				x.PrevExist.CodecEncodeSelf(e)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else if yyxt13 := z.Extension(z.I2Rtid(x.TTL)); yyxt13 != nil {
-					z.EncExtension(x.TTL, yyxt13)
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"TTL\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `TTL`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else if yyxt14 := z.Extension(z.I2Rtid(x.TTL)); yyxt14 != nil {
-					z.EncExtension(x.TTL, yyxt14)
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Refresh))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Refresh\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Refresh`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Refresh))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Dir\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Dir`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.NoValueOnSuccess))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"NoValueOnSuccess\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `NoValueOnSuccess`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.NoValueOnSuccess))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *SetOptions) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *SetOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "PrevValue":
-			if r.TryDecodeAsNil() {
-				x.PrevValue = ""
-			} else {
-				x.PrevValue = (string)(r.DecodeString())
-			}
-		case "PrevIndex":
-			if r.TryDecodeAsNil() {
-				x.PrevIndex = 0
-			} else {
-				x.PrevIndex = (uint64)(r.DecodeUint64())
-			}
-		case "PrevExist":
-			if r.TryDecodeAsNil() {
-				x.PrevExist = ""
-			} else {
-				x.PrevExist.CodecDecodeSelf(d)
-			}
-		case "TTL":
-			if r.TryDecodeAsNil() {
-				x.TTL = 0
-			} else {
-				if false {
-				} else if yyxt8 := z.Extension(z.I2Rtid(x.TTL)); yyxt8 != nil {
-					z.DecExtension(x.TTL, yyxt8)
-				} else {
-					x.TTL = (time.Duration)(r.DecodeInt64())
-				}
-			}
-		case "Refresh":
-			if r.TryDecodeAsNil() {
-				x.Refresh = false
-			} else {
-				x.Refresh = (bool)(r.DecodeBool())
-			}
-		case "Dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = false
-			} else {
-				x.Dir = (bool)(r.DecodeBool())
-			}
-		case "NoValueOnSuccess":
-			if r.TryDecodeAsNil() {
-				x.NoValueOnSuccess = false
-			} else {
-				x.NoValueOnSuccess = (bool)(r.DecodeBool())
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *SetOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj12 int
-	var yyb12 bool
-	var yyhl12 bool = l >= 0
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevValue = ""
-	} else {
-		x.PrevValue = (string)(r.DecodeString())
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevIndex = 0
-	} else {
-		x.PrevIndex = (uint64)(r.DecodeUint64())
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevExist = ""
-	} else {
-		x.PrevExist.CodecDecodeSelf(d)
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.TTL = 0
-	} else {
-		if false {
-		} else if yyxt17 := z.Extension(z.I2Rtid(x.TTL)); yyxt17 != nil {
-			z.DecExtension(x.TTL, yyxt17)
-		} else {
-			x.TTL = (time.Duration)(r.DecodeInt64())
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Refresh = false
-	} else {
-		x.Refresh = (bool)(r.DecodeBool())
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = false
-	} else {
-		x.Dir = (bool)(r.DecodeBool())
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.NoValueOnSuccess = false
-	} else {
-		x.NoValueOnSuccess = (bool)(r.DecodeBool())
-	}
-	for {
-		yyj12++
-		if yyhl12 {
-			yyb12 = yyj12 > l
-		} else {
-			yyb12 = r.CheckBreak()
-		}
-		if yyb12 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj12-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *GetOptions) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(3)
-			} else {
-				r.WriteMapStart(3)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Recursive\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Recursive`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Sort))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Sort\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Sort`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Sort))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Quorum))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Quorum\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Quorum`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Quorum))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *GetOptions) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *GetOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				x.Recursive = (bool)(r.DecodeBool())
-			}
-		case "Sort":
-			if r.TryDecodeAsNil() {
-				x.Sort = false
-			} else {
-				x.Sort = (bool)(r.DecodeBool())
-			}
-		case "Quorum":
-			if r.TryDecodeAsNil() {
-				x.Quorum = false
-			} else {
-				x.Quorum = (bool)(r.DecodeBool())
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *GetOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj7 int
-	var yyb7 bool
-	var yyhl7 bool = l >= 0
-	yyj7++
-	if yyhl7 {
-		yyb7 = yyj7 > l
-	} else {
-		yyb7 = r.CheckBreak()
-	}
-	if yyb7 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		x.Recursive = (bool)(r.DecodeBool())
-	}
-	yyj7++
-	if yyhl7 {
-		yyb7 = yyj7 > l
-	} else {
-		yyb7 = r.CheckBreak()
-	}
-	if yyb7 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Sort = false
-	} else {
-		x.Sort = (bool)(r.DecodeBool())
-	}
-	yyj7++
-	if yyhl7 {
-		yyb7 = yyj7 > l
-	} else {
-		yyb7 = r.CheckBreak()
-	}
-	if yyb7 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Quorum = false
-	} else {
-		x.Quorum = (bool)(r.DecodeBool())
-	}
-	for {
-		yyj7++
-		if yyhl7 {
-			yyb7 = yyj7 > l
-		} else {
-			yyb7 = r.CheckBreak()
-		}
-		if yyb7 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj7-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *DeleteOptions) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(4)
-			} else {
-				r.WriteMapStart(4)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.PrevValue))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"PrevValue\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `PrevValue`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.PrevValue))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"PrevIndex\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `PrevIndex`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Recursive\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Recursive`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Dir\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Dir`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *DeleteOptions) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *DeleteOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "PrevValue":
-			if r.TryDecodeAsNil() {
-				x.PrevValue = ""
-			} else {
-				x.PrevValue = (string)(r.DecodeString())
-			}
-		case "PrevIndex":
-			if r.TryDecodeAsNil() {
-				x.PrevIndex = 0
-			} else {
-				x.PrevIndex = (uint64)(r.DecodeUint64())
-			}
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				x.Recursive = (bool)(r.DecodeBool())
-			}
-		case "Dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = false
-			} else {
-				x.Dir = (bool)(r.DecodeBool())
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *DeleteOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj8 int
-	var yyb8 bool
-	var yyhl8 bool = l >= 0
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevValue = ""
-	} else {
-		x.PrevValue = (string)(r.DecodeString())
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevIndex = 0
-	} else {
-		x.PrevIndex = (uint64)(r.DecodeUint64())
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		x.Recursive = (bool)(r.DecodeBool())
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = false
-	} else {
-		x.Dir = (bool)(r.DecodeBool())
-	}
-	for {
-		yyj8++
-		if yyhl8 {
-			yyb8 = yyj8 > l
-		} else {
-			yyb8 = r.CheckBreak()
-		}
-		if yyb8 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj8-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *Response) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(3)
-			} else {
-				r.WriteMapStart(3)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Action))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"action\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `action`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Action))
-				}
-			}
-			var yyn6 bool
-			if x.Node == nil {
-				yyn6 = true
-				goto LABEL6
-			}
-		LABEL6:
-			if yyr2 || yy2arr2 {
-				if yyn6 {
-					r.WriteArrayElem()
-					r.EncodeNil()
-				} else {
-					r.WriteArrayElem()
-					if x.Node == nil {
-						r.EncodeNil()
-					} else {
-						x.Node.CodecEncodeSelf(e)
-					}
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"node\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `node`)
-				}
-				r.WriteMapElemValue()
-				if yyn6 {
-					r.EncodeNil()
-				} else {
-					if x.Node == nil {
-						r.EncodeNil()
-					} else {
-						x.Node.CodecEncodeSelf(e)
-					}
-				}
-			}
-			var yyn9 bool
-			if x.PrevNode == nil {
-				yyn9 = true
-				goto LABEL9
-			}
-		LABEL9:
-			if yyr2 || yy2arr2 {
-				if yyn9 {
-					r.WriteArrayElem()
-					r.EncodeNil()
-				} else {
-					r.WriteArrayElem()
-					if x.PrevNode == nil {
-						r.EncodeNil()
-					} else {
-						x.PrevNode.CodecEncodeSelf(e)
-					}
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"prevNode\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `prevNode`)
-				}
-				r.WriteMapElemValue()
-				if yyn9 {
-					r.EncodeNil()
-				} else {
-					if x.PrevNode == nil {
-						r.EncodeNil()
-					} else {
-						x.PrevNode.CodecEncodeSelf(e)
-					}
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *Response) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "action":
-			if r.TryDecodeAsNil() {
-				x.Action = ""
-			} else {
-				x.Action = (string)(r.DecodeString())
-			}
-		case "node":
-			if r.TryDecodeAsNil() {
-				if true && x.Node != nil {
-					x.Node = nil
-				}
-			} else {
-				if x.Node == nil {
-					x.Node = new(Node)
-				}
-
-				x.Node.CodecDecodeSelf(d)
-			}
-		case "prevNode":
-			if r.TryDecodeAsNil() {
-				if true && x.PrevNode != nil {
-					x.PrevNode = nil
-				}
-			} else {
-				if x.PrevNode == nil {
-					x.PrevNode = new(Node)
-				}
-
-				x.PrevNode.CodecDecodeSelf(d)
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj7 int
-	var yyb7 bool
-	var yyhl7 bool = l >= 0
-	yyj7++
-	if yyhl7 {
-		yyb7 = yyj7 > l
-	} else {
-		yyb7 = r.CheckBreak()
-	}
-	if yyb7 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Action = ""
-	} else {
-		x.Action = (string)(r.DecodeString())
-	}
-	yyj7++
-	if yyhl7 {
-		yyb7 = yyj7 > l
-	} else {
-		yyb7 = r.CheckBreak()
-	}
-	if yyb7 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		if true && x.Node != nil {
-			x.Node = nil
-		}
-	} else {
-		if x.Node == nil {
-			x.Node = new(Node)
-		}
-
-		x.Node.CodecDecodeSelf(d)
-	}
-	yyj7++
-	if yyhl7 {
-		yyb7 = yyj7 > l
-	} else {
-		yyb7 = r.CheckBreak()
-	}
-	if yyb7 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		if true && x.PrevNode != nil {
-			x.PrevNode = nil
-		}
-	} else {
-		if x.PrevNode == nil {
-			x.PrevNode = new(Node)
-		}
-
-		x.PrevNode.CodecDecodeSelf(d)
-	}
-	for {
-		yyj7++
-		if yyhl7 {
-			yyb7 = yyj7 > l
-		} else {
-			yyb7 = r.CheckBreak()
-		}
-		if yyb7 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj7-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			var yyq2 = [8]bool{     // should field at this index be written?
-				true,                // Key
-				x.Dir,               // Dir
-				true,                // Value
-				true,                // Nodes
-				true,                // CreatedIndex
-				true,                // ModifiedIndex
-				x.Expiration != nil, // Expiration
-				x.TTL != 0,          // TTL
-			}
-			_ = yyq2
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(8)
-			} else {
-				var yynn2 int
-				for _, b := range yyq2 {
-					if b {
-						yynn2++
-					}
-				}
-				r.WriteMapStart(yynn2)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Key))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"key\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `key`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Key))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if yyq2[1] {
-					if false {
-					} else {
-						r.EncodeBool(bool(x.Dir))
-					}
-				} else {
-					r.EncodeBool(false)
-				}
-			} else {
-				if yyq2[1] {
-					r.WriteMapElemKey()
-					if z.IsJSONHandle() {
-						z.WriteStr("\"dir\"")
-					} else {
-						r.EncodeStringEnc(codecSelferCcUTF89381, `dir`)
-					}
-					r.WriteMapElemValue()
-					if false {
-					} else {
-						r.EncodeBool(bool(x.Dir))
-					}
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Value))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"value\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `value`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Value))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if x.Nodes == nil {
-					r.EncodeNil()
-				} else {
-					x.Nodes.CodecEncodeSelf(e)
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"nodes\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `nodes`)
-				}
-				r.WriteMapElemValue()
-				if x.Nodes == nil {
-					r.EncodeNil()
-				} else {
-					x.Nodes.CodecEncodeSelf(e)
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.CreatedIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"createdIndex\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `createdIndex`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.CreatedIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.ModifiedIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"modifiedIndex\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `modifiedIndex`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.ModifiedIndex))
-				}
-			}
-			var yyn21 bool
-			if x.Expiration == nil {
-				yyn21 = true
-				goto LABEL21
-			}
-		LABEL21:
-			if yyr2 || yy2arr2 {
-				if yyn21 {
-					r.WriteArrayElem()
-					r.EncodeNil()
-				} else {
-					r.WriteArrayElem()
-					if yyq2[6] {
-						if x.Expiration == nil {
-							r.EncodeNil()
-						} else {
-							yy22 := *x.Expiration
-							if false {
-							} else if !z.EncBasicHandle().TimeNotBuiltin {
-								r.EncodeTime(yy22)
-							} else if yyxt23 := z.Extension(z.I2Rtid(yy22)); yyxt23 != nil {
-								z.EncExtension(yy22, yyxt23)
-							} else if z.EncBinary() {
-								z.EncBinaryMarshal(yy22)
-							} else if !z.EncBinary() && z.IsJSONHandle() {
-								z.EncJSONMarshal(yy22)
-							} else {
-								z.EncFallback(yy22)
-							}
-						}
-					} else {
-						r.EncodeNil()
-					}
-				}
-			} else {
-				if yyq2[6] {
-					r.WriteMapElemKey()
-					if z.IsJSONHandle() {
-						z.WriteStr("\"expiration\"")
-					} else {
-						r.EncodeStringEnc(codecSelferCcUTF89381, `expiration`)
-					}
-					r.WriteMapElemValue()
-					if yyn21 {
-						r.EncodeNil()
-					} else {
-						if x.Expiration == nil {
-							r.EncodeNil()
-						} else {
-							yy24 := *x.Expiration
-							if false {
-							} else if !z.EncBasicHandle().TimeNotBuiltin {
-								r.EncodeTime(yy24)
-							} else if yyxt25 := z.Extension(z.I2Rtid(yy24)); yyxt25 != nil {
-								z.EncExtension(yy24, yyxt25)
-							} else if z.EncBinary() {
-								z.EncBinaryMarshal(yy24)
-							} else if !z.EncBinary() && z.IsJSONHandle() {
-								z.EncJSONMarshal(yy24)
-							} else {
-								z.EncFallback(yy24)
-							}
-						}
-					}
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if yyq2[7] {
-					if false {
-					} else {
-						r.EncodeInt(int64(x.TTL))
-					}
-				} else {
-					r.EncodeInt(0)
-				}
-			} else {
-				if yyq2[7] {
-					r.WriteMapElemKey()
-					if z.IsJSONHandle() {
-						z.WriteStr("\"ttl\"")
-					} else {
-						r.EncodeStringEnc(codecSelferCcUTF89381, `ttl`)
-					}
-					r.WriteMapElemValue()
-					if false {
-					} else {
-						r.EncodeInt(int64(x.TTL))
-					}
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *Node) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "key":
-			if r.TryDecodeAsNil() {
-				x.Key = ""
-			} else {
-				x.Key = (string)(r.DecodeString())
-			}
-		case "dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = false
-			} else {
-				x.Dir = (bool)(r.DecodeBool())
-			}
-		case "value":
-			if r.TryDecodeAsNil() {
-				x.Value = ""
-			} else {
-				x.Value = (string)(r.DecodeString())
-			}
-		case "nodes":
-			if r.TryDecodeAsNil() {
-				x.Nodes = nil
-			} else {
-				x.Nodes.CodecDecodeSelf(d)
-			}
-		case "createdIndex":
-			if r.TryDecodeAsNil() {
-				x.CreatedIndex = 0
-			} else {
-				x.CreatedIndex = (uint64)(r.DecodeUint64())
-			}
-		case "modifiedIndex":
-			if r.TryDecodeAsNil() {
-				x.ModifiedIndex = 0
-			} else {
-				x.ModifiedIndex = (uint64)(r.DecodeUint64())
-			}
-		case "expiration":
-			if r.TryDecodeAsNil() {
-				if true && x.Expiration != nil {
-					x.Expiration = nil
-				}
-			} else {
-				if x.Expiration == nil {
-					x.Expiration = new(time.Time)
-				}
-
-				if false {
-				} else if !z.DecBasicHandle().TimeNotBuiltin {
-					*x.Expiration = r.DecodeTime()
-				} else if yyxt11 := z.Extension(z.I2Rtid(x.Expiration)); yyxt11 != nil {
-					z.DecExtension(x.Expiration, yyxt11)
-				} else if z.DecBinary() {
-					z.DecBinaryUnmarshal(x.Expiration)
-				} else if !z.DecBinary() && z.IsJSONHandle() {
-					z.DecJSONUnmarshal(x.Expiration)
-				} else {
-					z.DecFallback(x.Expiration, false)
-				}
-			}
-		case "ttl":
-			if r.TryDecodeAsNil() {
-				x.TTL = 0
-			} else {
-				x.TTL = (int64)(r.DecodeInt64())
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj13 int
-	var yyb13 bool
-	var yyhl13 bool = l >= 0
-	yyj13++
-	if yyhl13 {
-		yyb13 = yyj13 > l
-	} else {
-		yyb13 = r.CheckBreak()
-	}
-	if yyb13 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Key = ""
-	} else {
-		x.Key = (string)(r.DecodeString())
-	}
-	yyj13++
-	if yyhl13 {
-		yyb13 = yyj13 > l
-	} else {
-		yyb13 = r.CheckBreak()
-	}
-	if yyb13 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = false
-	} else {
-		x.Dir = (bool)(r.DecodeBool())
-	}
-	yyj13++
-	if yyhl13 {
-		yyb13 = yyj13 > l
-	} else {
-		yyb13 = r.CheckBreak()
-	}
-	if yyb13 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Value = ""
-	} else {
-		x.Value = (string)(r.DecodeString())
-	}
-	yyj13++
-	if yyhl13 {
-		yyb13 = yyj13 > l
-	} else {
-		yyb13 = r.CheckBreak()
-	}
-	if yyb13 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Nodes = nil
-	} else {
-		x.Nodes.CodecDecodeSelf(d)
-	}
-	yyj13++
-	if yyhl13 {
-		yyb13 = yyj13 > l
-	} else {
-		yyb13 = r.CheckBreak()
-	}
-	if yyb13 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.CreatedIndex = 0
-	} else {
-		x.CreatedIndex = (uint64)(r.DecodeUint64())
-	}
-	yyj13++
-	if yyhl13 {
-		yyb13 = yyj13 > l
-	} else {
-		yyb13 = r.CheckBreak()
-	}
-	if yyb13 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.ModifiedIndex = 0
-	} else {
-		x.ModifiedIndex = (uint64)(r.DecodeUint64())
-	}
-	yyj13++
-	if yyhl13 {
-		yyb13 = yyj13 > l
-	} else {
-		yyb13 = r.CheckBreak()
-	}
-	if yyb13 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		if true && x.Expiration != nil {
-			x.Expiration = nil
-		}
-	} else {
-		if x.Expiration == nil {
-			x.Expiration = new(time.Time)
-		}
-
-		if false {
-		} else if !z.DecBasicHandle().TimeNotBuiltin {
-			*x.Expiration = r.DecodeTime()
-		} else if yyxt21 := z.Extension(z.I2Rtid(x.Expiration)); yyxt21 != nil {
-			z.DecExtension(x.Expiration, yyxt21)
-		} else if z.DecBinary() {
-			z.DecBinaryUnmarshal(x.Expiration)
-		} else if !z.DecBinary() && z.IsJSONHandle() {
-			z.DecJSONUnmarshal(x.Expiration)
-		} else {
-			z.DecFallback(x.Expiration, false)
-		}
-	}
-	yyj13++
-	if yyhl13 {
-		yyb13 = yyj13 > l
-	} else {
-		yyb13 = r.CheckBreak()
-	}
-	if yyb13 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.TTL = 0
-	} else {
-		x.TTL = (int64)(r.DecodeInt64())
-	}
-	for {
-		yyj13++
-		if yyhl13 {
-			yyb13 = yyj13 > l
-		} else {
-			yyb13 = r.CheckBreak()
-		}
-		if yyb13 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj13-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x Nodes) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			h.encNodes((Nodes)(x), e)
-		}
-	}
-}
-
-func (x *Nodes) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		h.decNodes((*Nodes)(x), d)
-	}
-}
-
-func (x *httpKeysAPI) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(0)
-			} else {
-				r.WriteMapStart(0)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *httpKeysAPI) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *httpKeysAPI) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *httpKeysAPI) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj4 int
-	var yyb4 bool
-	var yyhl4 bool = l >= 0
-	for {
-		yyj4++
-		if yyhl4 {
-			yyb4 = yyj4 > l
-		} else {
-			yyb4 = r.CheckBreak()
-		}
-		if yyb4 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj4-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *httpWatcher) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(0)
-			} else {
-				r.WriteMapStart(0)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *httpWatcher) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *httpWatcher) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *httpWatcher) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj4 int
-	var yyb4 bool
-	var yyhl4 bool = l >= 0
-	for {
-		yyj4++
-		if yyhl4 {
-			yyb4 = yyj4 > l
-		} else {
-			yyb4 = r.CheckBreak()
-		}
-		if yyb4 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj4-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *getAction) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(5)
-			} else {
-				r.WriteMapStart(5)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Prefix))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Prefix\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Prefix`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Prefix))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Key))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Key\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Key`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Key))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Recursive\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Recursive`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Sorted))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Sorted\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Sorted`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Sorted))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Quorum))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Quorum\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Quorum`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Quorum))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *getAction) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *getAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Prefix":
-			if r.TryDecodeAsNil() {
-				x.Prefix = ""
-			} else {
-				x.Prefix = (string)(r.DecodeString())
-			}
-		case "Key":
-			if r.TryDecodeAsNil() {
-				x.Key = ""
-			} else {
-				x.Key = (string)(r.DecodeString())
-			}
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				x.Recursive = (bool)(r.DecodeBool())
-			}
-		case "Sorted":
-			if r.TryDecodeAsNil() {
-				x.Sorted = false
-			} else {
-				x.Sorted = (bool)(r.DecodeBool())
-			}
-		case "Quorum":
-			if r.TryDecodeAsNil() {
-				x.Quorum = false
-			} else {
-				x.Quorum = (bool)(r.DecodeBool())
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *getAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj9 int
-	var yyb9 bool
-	var yyhl9 bool = l >= 0
-	yyj9++
-	if yyhl9 {
-		yyb9 = yyj9 > l
-	} else {
-		yyb9 = r.CheckBreak()
-	}
-	if yyb9 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Prefix = ""
-	} else {
-		x.Prefix = (string)(r.DecodeString())
-	}
-	yyj9++
-	if yyhl9 {
-		yyb9 = yyj9 > l
-	} else {
-		yyb9 = r.CheckBreak()
-	}
-	if yyb9 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Key = ""
-	} else {
-		x.Key = (string)(r.DecodeString())
-	}
-	yyj9++
-	if yyhl9 {
-		yyb9 = yyj9 > l
-	} else {
-		yyb9 = r.CheckBreak()
-	}
-	if yyb9 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		x.Recursive = (bool)(r.DecodeBool())
-	}
-	yyj9++
-	if yyhl9 {
-		yyb9 = yyj9 > l
-	} else {
-		yyb9 = r.CheckBreak()
-	}
-	if yyb9 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Sorted = false
-	} else {
-		x.Sorted = (bool)(r.DecodeBool())
-	}
-	yyj9++
-	if yyhl9 {
-		yyb9 = yyj9 > l
-	} else {
-		yyb9 = r.CheckBreak()
-	}
-	if yyb9 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Quorum = false
-	} else {
-		x.Quorum = (bool)(r.DecodeBool())
-	}
-	for {
-		yyj9++
-		if yyhl9 {
-			yyb9 = yyj9 > l
-		} else {
-			yyb9 = r.CheckBreak()
-		}
-		if yyb9 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj9-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *waitAction) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(4)
-			} else {
-				r.WriteMapStart(4)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Prefix))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Prefix\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Prefix`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Prefix))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Key))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Key\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Key`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Key))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.WaitIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"WaitIndex\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `WaitIndex`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.WaitIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Recursive\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Recursive`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *waitAction) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *waitAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Prefix":
-			if r.TryDecodeAsNil() {
-				x.Prefix = ""
-			} else {
-				x.Prefix = (string)(r.DecodeString())
-			}
-		case "Key":
-			if r.TryDecodeAsNil() {
-				x.Key = ""
-			} else {
-				x.Key = (string)(r.DecodeString())
-			}
-		case "WaitIndex":
-			if r.TryDecodeAsNil() {
-				x.WaitIndex = 0
-			} else {
-				x.WaitIndex = (uint64)(r.DecodeUint64())
-			}
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				x.Recursive = (bool)(r.DecodeBool())
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *waitAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj8 int
-	var yyb8 bool
-	var yyhl8 bool = l >= 0
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Prefix = ""
-	} else {
-		x.Prefix = (string)(r.DecodeString())
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Key = ""
-	} else {
-		x.Key = (string)(r.DecodeString())
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.WaitIndex = 0
-	} else {
-		x.WaitIndex = (uint64)(r.DecodeUint64())
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		x.Recursive = (bool)(r.DecodeBool())
-	}
-	for {
-		yyj8++
-		if yyhl8 {
-			yyb8 = yyj8 > l
-		} else {
-			yyb8 = r.CheckBreak()
-		}
-		if yyb8 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj8-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *setAction) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(10)
-			} else {
-				r.WriteMapStart(10)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Prefix))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Prefix\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Prefix`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Prefix))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Key))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Key\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Key`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Key))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Value))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Value\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Value`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Value))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.PrevValue))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"PrevValue\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `PrevValue`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.PrevValue))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"PrevIndex\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `PrevIndex`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				x.PrevExist.CodecEncodeSelf(e)
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"PrevExist\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `PrevExist`)
-				}
-				r.WriteMapElemValue()
-				x.PrevExist.CodecEncodeSelf(e)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else if yyxt22 := z.Extension(z.I2Rtid(x.TTL)); yyxt22 != nil {
-					z.EncExtension(x.TTL, yyxt22)
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"TTL\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `TTL`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else if yyxt23 := z.Extension(z.I2Rtid(x.TTL)); yyxt23 != nil {
-					z.EncExtension(x.TTL, yyxt23)
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Refresh))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Refresh\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Refresh`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Refresh))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Dir\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Dir`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.NoValueOnSuccess))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"NoValueOnSuccess\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `NoValueOnSuccess`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.NoValueOnSuccess))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *setAction) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *setAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Prefix":
-			if r.TryDecodeAsNil() {
-				x.Prefix = ""
-			} else {
-				x.Prefix = (string)(r.DecodeString())
-			}
-		case "Key":
-			if r.TryDecodeAsNil() {
-				x.Key = ""
-			} else {
-				x.Key = (string)(r.DecodeString())
-			}
-		case "Value":
-			if r.TryDecodeAsNil() {
-				x.Value = ""
-			} else {
-				x.Value = (string)(r.DecodeString())
-			}
-		case "PrevValue":
-			if r.TryDecodeAsNil() {
-				x.PrevValue = ""
-			} else {
-				x.PrevValue = (string)(r.DecodeString())
-			}
-		case "PrevIndex":
-			if r.TryDecodeAsNil() {
-				x.PrevIndex = 0
-			} else {
-				x.PrevIndex = (uint64)(r.DecodeUint64())
-			}
-		case "PrevExist":
-			if r.TryDecodeAsNil() {
-				x.PrevExist = ""
-			} else {
-				x.PrevExist.CodecDecodeSelf(d)
-			}
-		case "TTL":
-			if r.TryDecodeAsNil() {
-				x.TTL = 0
-			} else {
-				if false {
-				} else if yyxt11 := z.Extension(z.I2Rtid(x.TTL)); yyxt11 != nil {
-					z.DecExtension(x.TTL, yyxt11)
-				} else {
-					x.TTL = (time.Duration)(r.DecodeInt64())
-				}
-			}
-		case "Refresh":
-			if r.TryDecodeAsNil() {
-				x.Refresh = false
-			} else {
-				x.Refresh = (bool)(r.DecodeBool())
-			}
-		case "Dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = false
-			} else {
-				x.Dir = (bool)(r.DecodeBool())
-			}
-		case "NoValueOnSuccess":
-			if r.TryDecodeAsNil() {
-				x.NoValueOnSuccess = false
-			} else {
-				x.NoValueOnSuccess = (bool)(r.DecodeBool())
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *setAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj15 int
-	var yyb15 bool
-	var yyhl15 bool = l >= 0
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Prefix = ""
-	} else {
-		x.Prefix = (string)(r.DecodeString())
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Key = ""
-	} else {
-		x.Key = (string)(r.DecodeString())
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Value = ""
-	} else {
-		x.Value = (string)(r.DecodeString())
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevValue = ""
-	} else {
-		x.PrevValue = (string)(r.DecodeString())
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevIndex = 0
-	} else {
-		x.PrevIndex = (uint64)(r.DecodeUint64())
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevExist = ""
-	} else {
-		x.PrevExist.CodecDecodeSelf(d)
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.TTL = 0
-	} else {
-		if false {
-		} else if yyxt23 := z.Extension(z.I2Rtid(x.TTL)); yyxt23 != nil {
-			z.DecExtension(x.TTL, yyxt23)
-		} else {
-			x.TTL = (time.Duration)(r.DecodeInt64())
-		}
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Refresh = false
-	} else {
-		x.Refresh = (bool)(r.DecodeBool())
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = false
-	} else {
-		x.Dir = (bool)(r.DecodeBool())
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.NoValueOnSuccess = false
-	} else {
-		x.NoValueOnSuccess = (bool)(r.DecodeBool())
-	}
-	for {
-		yyj15++
-		if yyhl15 {
-			yyb15 = yyj15 > l
-		} else {
-			yyb15 = r.CheckBreak()
-		}
-		if yyb15 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj15-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *deleteAction) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(6)
-			} else {
-				r.WriteMapStart(6)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Prefix))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Prefix\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Prefix`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Prefix))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Key))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Key\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Key`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Key))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.PrevValue))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"PrevValue\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `PrevValue`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.PrevValue))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"PrevIndex\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `PrevIndex`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Dir\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Dir`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Recursive\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Recursive`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *deleteAction) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *deleteAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Prefix":
-			if r.TryDecodeAsNil() {
-				x.Prefix = ""
-			} else {
-				x.Prefix = (string)(r.DecodeString())
-			}
-		case "Key":
-			if r.TryDecodeAsNil() {
-				x.Key = ""
-			} else {
-				x.Key = (string)(r.DecodeString())
-			}
-		case "PrevValue":
-			if r.TryDecodeAsNil() {
-				x.PrevValue = ""
-			} else {
-				x.PrevValue = (string)(r.DecodeString())
-			}
-		case "PrevIndex":
-			if r.TryDecodeAsNil() {
-				x.PrevIndex = 0
-			} else {
-				x.PrevIndex = (uint64)(r.DecodeUint64())
-			}
-		case "Dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = false
-			} else {
-				x.Dir = (bool)(r.DecodeBool())
-			}
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				x.Recursive = (bool)(r.DecodeBool())
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *deleteAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj10 int
-	var yyb10 bool
-	var yyhl10 bool = l >= 0
-	yyj10++
-	if yyhl10 {
-		yyb10 = yyj10 > l
-	} else {
-		yyb10 = r.CheckBreak()
-	}
-	if yyb10 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Prefix = ""
-	} else {
-		x.Prefix = (string)(r.DecodeString())
-	}
-	yyj10++
-	if yyhl10 {
-		yyb10 = yyj10 > l
-	} else {
-		yyb10 = r.CheckBreak()
-	}
-	if yyb10 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Key = ""
-	} else {
-		x.Key = (string)(r.DecodeString())
-	}
-	yyj10++
-	if yyhl10 {
-		yyb10 = yyj10 > l
-	} else {
-		yyb10 = r.CheckBreak()
-	}
-	if yyb10 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevValue = ""
-	} else {
-		x.PrevValue = (string)(r.DecodeString())
-	}
-	yyj10++
-	if yyhl10 {
-		yyb10 = yyj10 > l
-	} else {
-		yyb10 = r.CheckBreak()
-	}
-	if yyb10 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevIndex = 0
-	} else {
-		x.PrevIndex = (uint64)(r.DecodeUint64())
-	}
-	yyj10++
-	if yyhl10 {
-		yyb10 = yyj10 > l
-	} else {
-		yyb10 = r.CheckBreak()
-	}
-	if yyb10 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = false
-	} else {
-		x.Dir = (bool)(r.DecodeBool())
-	}
-	yyj10++
-	if yyhl10 {
-		yyb10 = yyj10 > l
-	} else {
-		yyb10 = r.CheckBreak()
-	}
-	if yyb10 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		x.Recursive = (bool)(r.DecodeBool())
-	}
-	for {
-		yyj10++
-		if yyhl10 {
-			yyb10 = yyj10 > l
-		} else {
-			yyb10 = r.CheckBreak()
-		}
-		if yyb10 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj10-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *createInOrderAction) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		if false {
-		} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-			z.EncExtension(x, yyxt1)
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false // struct tag has 'toArray'
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(4)
-			} else {
-				r.WriteMapStart(4)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Prefix))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Prefix\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Prefix`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Prefix))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Dir))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Dir\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Dir`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Dir))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Value))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"Value\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `Value`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, string(x.Value))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if false {
-				} else if yyxt13 := z.Extension(z.I2Rtid(x.TTL)); yyxt13 != nil {
-					z.EncExtension(x.TTL, yyxt13)
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			} else {
-				r.WriteMapElemKey()
-				if z.IsJSONHandle() {
-					z.WriteStr("\"TTL\"")
-				} else {
-					r.EncodeStringEnc(codecSelferCcUTF89381, `TTL`)
-				}
-				r.WriteMapElemValue()
-				if false {
-				} else if yyxt14 := z.Extension(z.I2Rtid(x.TTL)); yyxt14 != nil {
-					z.EncExtension(x.TTL, yyxt14)
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *createInOrderAction) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	if false {
-	} else if yyxt1 := z.Extension(z.I2Rtid(x)); yyxt1 != nil {
-		z.DecExtension(x, yyxt1)
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap9381 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray9381 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(errCodecSelferOnlyMapOrArrayEncodeToStruct9381)
-		}
-	}
-}
-
-func (x *createInOrderAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3 := z.StringView(r.DecodeStringAsBytes())
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Prefix":
-			if r.TryDecodeAsNil() {
-				x.Prefix = ""
-			} else {
-				x.Prefix = (string)(r.DecodeString())
-			}
-		case "Dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = ""
-			} else {
-				x.Dir = (string)(r.DecodeString())
-			}
-		case "Value":
-			if r.TryDecodeAsNil() {
-				x.Value = ""
-			} else {
-				x.Value = (string)(r.DecodeString())
-			}
-		case "TTL":
-			if r.TryDecodeAsNil() {
-				x.TTL = 0
-			} else {
-				if false {
-				} else if yyxt8 := z.Extension(z.I2Rtid(x.TTL)); yyxt8 != nil {
-					z.DecExtension(x.TTL, yyxt8)
-				} else {
-					x.TTL = (time.Duration)(r.DecodeInt64())
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *createInOrderAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj9 int
-	var yyb9 bool
-	var yyhl9 bool = l >= 0
-	yyj9++
-	if yyhl9 {
-		yyb9 = yyj9 > l
-	} else {
-		yyb9 = r.CheckBreak()
-	}
-	if yyb9 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Prefix = ""
-	} else {
-		x.Prefix = (string)(r.DecodeString())
-	}
-	yyj9++
-	if yyhl9 {
-		yyb9 = yyj9 > l
-	} else {
-		yyb9 = r.CheckBreak()
-	}
-	if yyb9 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = ""
-	} else {
-		x.Dir = (string)(r.DecodeString())
-	}
-	yyj9++
-	if yyhl9 {
-		yyb9 = yyj9 > l
-	} else {
-		yyb9 = r.CheckBreak()
-	}
-	if yyb9 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Value = ""
-	} else {
-		x.Value = (string)(r.DecodeString())
-	}
-	yyj9++
-	if yyhl9 {
-		yyb9 = yyj9 > l
-	} else {
-		yyb9 = r.CheckBreak()
-	}
-	if yyb9 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.TTL = 0
-	} else {
-		if false {
-		} else if yyxt14 := z.Extension(z.I2Rtid(x.TTL)); yyxt14 != nil {
-			z.DecExtension(x.TTL, yyxt14)
-		} else {
-			x.TTL = (time.Duration)(r.DecodeInt64())
-		}
-	}
-	for {
-		yyj9++
-		if yyhl9 {
-			yyb9 = yyj9 > l
-		} else {
-			yyb9 = r.CheckBreak()
-		}
-		if yyb9 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj9-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x codecSelfer9381) encNodes(v Nodes, e *codec1978.Encoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	r.WriteArrayStart(len(v))
-	for _, yyv1 := range v {
-		r.WriteArrayElem()
-		if yyv1 == nil {
-			r.EncodeNil()
-		} else {
-			yyv1.CodecEncodeSelf(e)
-		}
-	}
-	r.WriteArrayEnd()
-}
-
-func (x codecSelfer9381) decNodes(v *Nodes, d *codec1978.Decoder) {
-	var h codecSelfer9381
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-
-	yyv1 := *v
-	yyh1, yyl1 := z.DecSliceHelperStart()
-	var yyc1 bool
-	_ = yyc1
-	if yyl1 == 0 {
-		if yyv1 == nil {
-			yyv1 = []*Node{}
-			yyc1 = true
-		} else if len(yyv1) != 0 {
-			yyv1 = yyv1[:0]
-			yyc1 = true
-		}
-	} else {
-		yyhl1 := yyl1 > 0
-		var yyrl1 int
-		_ = yyrl1
-		if yyhl1 {
-			if yyl1 > cap(yyv1) {
-				yyrl1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 8)
-				if yyrl1 <= cap(yyv1) {
-					yyv1 = yyv1[:yyrl1]
-				} else {
-					yyv1 = make([]*Node, yyrl1)
-				}
-				yyc1 = true
-			} else if yyl1 != len(yyv1) {
-				yyv1 = yyv1[:yyl1]
-				yyc1 = true
-			}
-		}
-		var yyj1 int
-		// var yydn1 bool
-		for yyj1 = 0; (yyhl1 && yyj1 < yyl1) || !(yyhl1 || r.CheckBreak()); yyj1++ { // bounds-check-elimination
-			if yyj1 == 0 && yyv1 == nil {
-				if yyhl1 {
-					yyrl1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 8)
-				} else {
-					yyrl1 = 8
-				}
-				yyv1 = make([]*Node, yyrl1)
-				yyc1 = true
-			}
-			yyh1.ElemContainerState(yyj1)
-
-			var yydb1 bool
-			if yyj1 >= len(yyv1) {
-				yyv1 = append(yyv1, nil)
-				yyc1 = true
-
-			}
-			if yydb1 {
-				z.DecSwallow()
-			} else {
-				if r.TryDecodeAsNil() {
-					yyv1[yyj1] = nil
-				} else {
-					if yyv1[yyj1] == nil {
-						yyv1[yyj1] = new(Node)
-					}
-					yyv1[yyj1].CodecDecodeSelf(d)
-				}
-
-			}
-
-		}
-		if yyj1 < len(yyv1) {
-			yyv1 = yyv1[:yyj1]
-			yyc1 = true
-		} else if yyj1 == 0 && yyv1 == nil {
-			yyv1 = make([]*Node, 0)
-			yyc1 = true
-		}
-	}
-	yyh1.End()
-	if yyc1 {
-		*v = yyv1
-	}
-}

+ 4 - 6
client/keys.go

@@ -14,21 +14,17 @@
 
 package client
 
-//go:generate codecgen -d 1819 -r "Node|Response|Nodes" -o keys.generated.go keys.go
-
 import (
 	"context"
 	"encoding/json"
 	"errors"
 	"fmt"
+	"go.etcd.io/etcd/pkg/pathutil"
 	"net/http"
 	"net/url"
 	"strconv"
 	"strings"
 	"time"
-
-	"github.com/ugorji/go/codec"
-	"go.etcd.io/etcd/pkg/pathutil"
 )
 
 const (
@@ -656,9 +652,11 @@ func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Resp
 	return res, err
 }
 
+var jsonIterator = caseSensitiveJsonIterator()
+
 func unmarshalSuccessfulKeysResponse(header http.Header, body []byte) (*Response, error) {
 	var res Response
-	err := codec.NewDecoderBytes(body, new(codec.JsonHandle)).Decode(&res)
+	err := jsonIterator.Unmarshal(body, &res)
 	if err != nil {
 		return nil, ErrInvalidJSON
 	}

+ 3 - 1
go.mod

@@ -23,11 +23,14 @@ require (
 	github.com/grpc-ecosystem/grpc-gateway v1.4.1
 	github.com/inconshreveable/mousetrap v1.0.0 // indirect
 	github.com/jonboulle/clockwork v0.1.0
+	github.com/json-iterator/go v1.1.5
 	github.com/kr/pty v1.0.0
 	github.com/mattn/go-colorable v0.0.9 // indirect
 	github.com/mattn/go-isatty v0.0.4 // indirect
 	github.com/mattn/go-runewidth v0.0.2 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.0 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.1
 	github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5
 	github.com/onsi/gomega v1.4.2 // indirect
 	github.com/pkg/errors v0.8.0 // indirect
@@ -42,7 +45,6 @@ require (
 	github.com/spf13/pflag v1.0.1
 	github.com/stretchr/testify v1.2.2 // indirect
 	github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8
-	github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43
 	github.com/urfave/cli v1.20.0
 	github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2
 	go.etcd.io/bbolt v1.3.2

+ 6 - 4
go.sum

@@ -46,6 +46,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE=
+github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/kr/pty v1.0.0 h1:jR04h3bskdxb8xt+5B6MoxPwDhMCe0oEgxug4Ca1YSA=
 github.com/kr/pty v1.0.0/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
@@ -56,6 +58,10 @@ github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC
 github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
 github.com/matttproud/golang_protobuf_extensions v1.0.0 h1:YNOwxxSJzSUARoD9KRZLzM9Y858MNGCOACTvCW9TSAc=
 github.com/matttproud/golang_protobuf_extensions v1.0.0/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5 h1:58+kh9C6jJVXYjt8IE48G2eWl6BjwU5Gj0gqY84fy78=
 github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
 github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
@@ -86,10 +92,6 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs=
-github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
-github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43 h1:BasDe+IErOQKrMVXab7UayvSlIpiyGwRvuX3EKYY7UA=
-github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
 github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=

+ 0 - 18
scripts/update-clientv2.sh

@@ -1,18 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-if ! [[ "$0" =~ scripts/update-clientv2.sh ]]; then
-	echo "must be run from repository root"
-	exit 255
-fi
-
-echo "installing 'client/keys.generated.go'"
-go get -v -u github.com/ugorji/go/codec/codecgen
-
-echo "generating client/keys.generated.go"
-pushd client
-codecgen -o ./keys.generated.go ./keys.go
-popd
-
-echo "generated client/keys.generated.go"

+ 0 - 90
vendor/github.com/coreos/go-systemd/util/util.go

@@ -1,90 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package util contains utility functions related to systemd that applications
-// can use to check things like whether systemd is running.  Note that some of
-// these functions attempt to manually load systemd libraries at runtime rather
-// than linking against them.
-package util
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"strings"
-)
-
-var (
-	ErrNoCGO = fmt.Errorf("go-systemd built with CGO disabled")
-)
-
-// GetRunningSlice attempts to retrieve the name of the systemd slice in which
-// the current process is running.
-// This function is a wrapper around the libsystemd C library; if it cannot be
-// opened, an error is returned.
-func GetRunningSlice() (string, error) {
-	return getRunningSlice()
-}
-
-// RunningFromSystemService tries to detect whether the current process has
-// been invoked from a system service. The condition for this is whether the
-// process is _not_ a user process. User processes are those running in session
-// scopes or under per-user `systemd --user` instances.
-//
-// To avoid false positives on systems without `pam_systemd` (which is
-// responsible for creating user sessions), this function also uses a heuristic
-// to detect whether it's being invoked from a session leader process. This is
-// the case if the current process is executed directly from a service file
-// (e.g. with `ExecStart=/this/cmd`). Note that this heuristic will fail if the
-// command is instead launched in a subshell or similar so that it is not
-// session leader (e.g. `ExecStart=/bin/bash -c "/this/cmd"`)
-//
-// This function is a wrapper around the libsystemd C library; if this is
-// unable to successfully open a handle to the library for any reason (e.g. it
-// cannot be found), an error will be returned.
-func RunningFromSystemService() (bool, error) {
-	return runningFromSystemService()
-}
-
-// CurrentUnitName attempts to retrieve the name of the systemd system unit
-// from which the calling process has been invoked. It wraps the systemd
-// `sd_pid_get_unit` call, with the same caveat: for processes not part of a
-// systemd system unit, this function will return an error.
-func CurrentUnitName() (string, error) {
-	return currentUnitName()
-}
-
-// IsRunningSystemd checks whether the host was booted with systemd as its init
-// system. This functions similarly to systemd's `sd_booted(3)`: internally, it
-// checks whether /run/systemd/system/ exists and is a directory.
-// http://www.freedesktop.org/software/systemd/man/sd_booted.html
-func IsRunningSystemd() bool {
-	fi, err := os.Lstat("/run/systemd/system")
-	if err != nil {
-		return false
-	}
-	return fi.IsDir()
-}
-
-// GetMachineID returns a host's 128-bit machine ID as a string. This functions
-// similarly to systemd's `sd_id128_get_machine`: internally, it simply reads
-// the contents of /etc/machine-id
-// http://www.freedesktop.org/software/systemd/man/sd_id128_get_machine.html
-func GetMachineID() (string, error) {
-	machineID, err := ioutil.ReadFile("/etc/machine-id")
-	if err != nil {
-		return "", fmt.Errorf("failed to read /etc/machine-id: %v", err)
-	}
-	return strings.TrimSpace(string(machineID)), nil
-}

+ 0 - 175
vendor/github.com/coreos/go-systemd/util/util_cgo.go

@@ -1,175 +0,0 @@
-// Copyright 2016 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build cgo
-
-package util
-
-// #include <stdlib.h>
-// #include <sys/types.h>
-// #include <unistd.h>
-//
-// int
-// my_sd_pid_get_owner_uid(void *f, pid_t pid, uid_t *uid)
-// {
-//   int (*sd_pid_get_owner_uid)(pid_t, uid_t *);
-//
-//   sd_pid_get_owner_uid = (int (*)(pid_t, uid_t *))f;
-//   return sd_pid_get_owner_uid(pid, uid);
-// }
-//
-// int
-// my_sd_pid_get_unit(void *f, pid_t pid, char **unit)
-// {
-//   int (*sd_pid_get_unit)(pid_t, char **);
-//
-//   sd_pid_get_unit = (int (*)(pid_t, char **))f;
-//   return sd_pid_get_unit(pid, unit);
-// }
-//
-// int
-// my_sd_pid_get_slice(void *f, pid_t pid, char **slice)
-// {
-//   int (*sd_pid_get_slice)(pid_t, char **);
-//
-//   sd_pid_get_slice = (int (*)(pid_t, char **))f;
-//   return sd_pid_get_slice(pid, slice);
-// }
-//
-// int
-// am_session_leader()
-// {
-//   return (getsid(0) == getpid());
-// }
-import "C"
-import (
-	"fmt"
-	"syscall"
-	"unsafe"
-
-	"github.com/coreos/pkg/dlopen"
-)
-
-var libsystemdNames = []string{
-	// systemd < 209
-	"libsystemd-login.so.0",
-	"libsystemd-login.so",
-
-	// systemd >= 209 merged libsystemd-login into libsystemd proper
-	"libsystemd.so.0",
-	"libsystemd.so",
-}
-
-func getRunningSlice() (slice string, err error) {
-	var h *dlopen.LibHandle
-	h, err = dlopen.GetHandle(libsystemdNames)
-	if err != nil {
-		return
-	}
-	defer func() {
-		if err1 := h.Close(); err1 != nil {
-			err = err1
-		}
-	}()
-
-	sd_pid_get_slice, err := h.GetSymbolPointer("sd_pid_get_slice")
-	if err != nil {
-		return
-	}
-
-	var s string
-	sl := C.CString(s)
-	defer C.free(unsafe.Pointer(sl))
-
-	ret := C.my_sd_pid_get_slice(sd_pid_get_slice, 0, &sl)
-	if ret < 0 {
-		err = fmt.Errorf("error calling sd_pid_get_slice: %v", syscall.Errno(-ret))
-		return
-	}
-
-	return C.GoString(sl), nil
-}
-
-func runningFromSystemService() (ret bool, err error) {
-	var h *dlopen.LibHandle
-	h, err = dlopen.GetHandle(libsystemdNames)
-	if err != nil {
-		return
-	}
-	defer func() {
-		if err1 := h.Close(); err1 != nil {
-			err = err1
-		}
-	}()
-
-	sd_pid_get_owner_uid, err := h.GetSymbolPointer("sd_pid_get_owner_uid")
-	if err != nil {
-		return
-	}
-
-	var uid C.uid_t
-	errno := C.my_sd_pid_get_owner_uid(sd_pid_get_owner_uid, 0, &uid)
-	serrno := syscall.Errno(-errno)
-	// when we're running from a unit file, sd_pid_get_owner_uid returns
-	// ENOENT (systemd <220), ENXIO (systemd 220-223), or ENODATA
-	// (systemd >=234)
-	switch {
-	case errno >= 0:
-		ret = false
-	case serrno == syscall.ENOENT, serrno == syscall.ENXIO, serrno == syscall.ENODATA:
-		// Since the implementation of sessions in systemd relies on
-		// the `pam_systemd` module, using the sd_pid_get_owner_uid
-		// heuristic alone can result in false positives if that module
-		// (or PAM itself) is not present or properly configured on the
-		// system. As such, we also check if we're the session leader,
-		// which should be the case if we're invoked from a unit file,
-		// but not if e.g. we're invoked from the command line from a
-		// user's login session
-		ret = C.am_session_leader() == 1
-	default:
-		err = fmt.Errorf("error calling sd_pid_get_owner_uid: %v", syscall.Errno(-errno))
-	}
-	return
-}
-
-func currentUnitName() (unit string, err error) {
-	var h *dlopen.LibHandle
-	h, err = dlopen.GetHandle(libsystemdNames)
-	if err != nil {
-		return
-	}
-	defer func() {
-		if err1 := h.Close(); err1 != nil {
-			err = err1
-		}
-	}()
-
-	sd_pid_get_unit, err := h.GetSymbolPointer("sd_pid_get_unit")
-	if err != nil {
-		return
-	}
-
-	var s string
-	u := C.CString(s)
-	defer C.free(unsafe.Pointer(u))
-
-	ret := C.my_sd_pid_get_unit(sd_pid_get_unit, 0, &u)
-	if ret < 0 {
-		err = fmt.Errorf("error calling sd_pid_get_unit: %v", syscall.Errno(-ret))
-		return
-	}
-
-	unit = C.GoString(u)
-	return
-}

+ 0 - 23
vendor/github.com/coreos/go-systemd/util/util_stub.go

@@ -1,23 +0,0 @@
-// Copyright 2016 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !cgo
-
-package util
-
-func getRunningSlice() (string, error) { return "", ErrNoCGO }
-
-func runningFromSystemService() (bool, error) { return false, ErrNoCGO }
-
-func currentUnitName() (string, error) { return "", ErrNoCGO }

+ 0 - 82
vendor/github.com/coreos/pkg/dlopen/dlopen.go

@@ -1,82 +0,0 @@
-// Copyright 2016 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package dlopen provides some convenience functions to dlopen a library and
-// get its symbols.
-package dlopen
-
-// #cgo LDFLAGS: -ldl
-// #include <stdlib.h>
-// #include <dlfcn.h>
-import "C"
-import (
-	"errors"
-	"fmt"
-	"unsafe"
-)
-
-var ErrSoNotFound = errors.New("unable to open a handle to the library")
-
-// LibHandle represents an open handle to a library (.so)
-type LibHandle struct {
-	Handle  unsafe.Pointer
-	Libname string
-}
-
-// GetHandle tries to get a handle to a library (.so), attempting to access it
-// by the names specified in libs and returning the first that is successfully
-// opened. Callers are responsible for closing the handler. If no library can
-// be successfully opened, an error is returned.
-func GetHandle(libs []string) (*LibHandle, error) {
-	for _, name := range libs {
-		libname := C.CString(name)
-		defer C.free(unsafe.Pointer(libname))
-		handle := C.dlopen(libname, C.RTLD_LAZY)
-		if handle != nil {
-			h := &LibHandle{
-				Handle:  handle,
-				Libname: name,
-			}
-			return h, nil
-		}
-	}
-	return nil, ErrSoNotFound
-}
-
-// GetSymbolPointer takes a symbol name and returns a pointer to the symbol.
-func (l *LibHandle) GetSymbolPointer(symbol string) (unsafe.Pointer, error) {
-	sym := C.CString(symbol)
-	defer C.free(unsafe.Pointer(sym))
-
-	C.dlerror()
-	p := C.dlsym(l.Handle, sym)
-	e := C.dlerror()
-	if e != nil {
-		return nil, fmt.Errorf("error resolving symbol %q: %v", symbol, errors.New(C.GoString(e)))
-	}
-
-	return p, nil
-}
-
-// Close closes a LibHandle.
-func (l *LibHandle) Close() error {
-	C.dlerror()
-	C.dlclose(l.Handle)
-	e := C.dlerror()
-	if e != nil {
-		return fmt.Errorf("error closing %v: %v", l.Libname, errors.New(C.GoString(e)))
-	}
-
-	return nil
-}

+ 0 - 56
vendor/github.com/coreos/pkg/dlopen/dlopen_example.go

@@ -1,56 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// +build linux
-
-package dlopen
-
-// #include <string.h>
-// #include <stdlib.h>
-//
-// int
-// my_strlen(void *f, const char *s)
-// {
-//   size_t (*strlen)(const char *);
-//
-//   strlen = (size_t (*)(const char *))f;
-//   return strlen(s);
-// }
-import "C"
-
-import (
-	"fmt"
-	"unsafe"
-)
-
-func strlen(libs []string, s string) (int, error) {
-	h, err := GetHandle(libs)
-	if err != nil {
-		return -1, fmt.Errorf(`couldn't get a handle to the library: %v`, err)
-	}
-	defer h.Close()
-
-	f := "strlen"
-	cs := C.CString(s)
-	defer C.free(unsafe.Pointer(cs))
-
-	strlen, err := h.GetSymbolPointer(f)
-	if err != nil {
-		return -1, fmt.Errorf(`couldn't get symbol %q: %v`, f, err)
-	}
-
-	len := C.my_strlen(strlen, cs)
-
-	return int(len), nil
-}

+ 2 - 3
vendor/github.com/ugorji/go/codec/LICENSE → vendor/github.com/json-iterator/go/LICENSE

@@ -1,7 +1,6 @@
-The MIT License (MIT)
+MIT License
 
-Copyright (c) 2012-2015 Ugorji Nwoke.
-All rights reserved.
+Copyright (c) 2016 json-iterator
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal

+ 150 - 0
vendor/github.com/json-iterator/go/adapter.go

@@ -0,0 +1,150 @@
+package jsoniter
+
+import (
+	"bytes"
+	"io"
+)
+
+// RawMessage to make replace json with jsoniter
+type RawMessage []byte
+
+// Unmarshal adapts to json/encoding Unmarshal API
+//
+// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v.
+// Refer to https://godoc.org/encoding/json#Unmarshal for more information
+func Unmarshal(data []byte, v interface{}) error {
+	return ConfigDefault.Unmarshal(data, v)
+}
+
+// UnmarshalFromString convenient method to read from string instead of []byte
+func UnmarshalFromString(str string, v interface{}) error {
+	return ConfigDefault.UnmarshalFromString(str, v)
+}
+
+// Get quick method to get value from deeply nested JSON structure
+func Get(data []byte, path ...interface{}) Any {
+	return ConfigDefault.Get(data, path...)
+}
+
+// Marshal adapts to json/encoding Marshal API
+//
+// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API
+// Refer to https://godoc.org/encoding/json#Marshal for more information
+func Marshal(v interface{}) ([]byte, error) {
+	return ConfigDefault.Marshal(v)
+}
+
+// MarshalIndent same as json.MarshalIndent. Prefix is not supported.
+func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
+	return ConfigDefault.MarshalIndent(v, prefix, indent)
+}
+
+// MarshalToString convenient method to write as string instead of []byte
+func MarshalToString(v interface{}) (string, error) {
+	return ConfigDefault.MarshalToString(v)
+}
+
+// NewDecoder adapts to json/stream NewDecoder API.
+//
+// NewDecoder returns a new decoder that reads from r.
+//
+// Instead of a json/encoding Decoder, an Decoder is returned
+// Refer to https://godoc.org/encoding/json#NewDecoder for more information
+func NewDecoder(reader io.Reader) *Decoder {
+	return ConfigDefault.NewDecoder(reader)
+}
+
+// Decoder reads and decodes JSON values from an input stream.
+// Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress)
+type Decoder struct {
+	iter *Iterator
+}
+
+// Decode decode JSON into interface{}
+func (adapter *Decoder) Decode(obj interface{}) error {
+	if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil {
+		if !adapter.iter.loadMore() {
+			return io.EOF
+		}
+	}
+	adapter.iter.ReadVal(obj)
+	err := adapter.iter.Error
+	if err == io.EOF {
+		return nil
+	}
+	return adapter.iter.Error
+}
+
+// More is there more?
+func (adapter *Decoder) More() bool {
+	iter := adapter.iter
+	if iter.Error != nil {
+		return false
+	}
+	c := iter.nextToken()
+	if c == 0 {
+		return false
+	}
+	iter.unreadByte()
+	return c != ']' && c != '}'
+}
+
+// Buffered remaining buffer
+func (adapter *Decoder) Buffered() io.Reader {
+	remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail]
+	return bytes.NewReader(remaining)
+}
+
+// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
+// Number instead of as a float64.
+func (adapter *Decoder) UseNumber() {
+	cfg := adapter.iter.cfg.configBeforeFrozen
+	cfg.UseNumber = true
+	adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions)
+}
+
+// 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 (adapter *Decoder) DisallowUnknownFields() {
+	cfg := adapter.iter.cfg.configBeforeFrozen
+	cfg.DisallowUnknownFields = true
+	adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions)
+}
+
+// NewEncoder same as json.NewEncoder
+func NewEncoder(writer io.Writer) *Encoder {
+	return ConfigDefault.NewEncoder(writer)
+}
+
+// Encoder same as json.Encoder
+type Encoder struct {
+	stream *Stream
+}
+
+// Encode encode interface{} as JSON to io.Writer
+func (adapter *Encoder) Encode(val interface{}) error {
+	adapter.stream.WriteVal(val)
+	adapter.stream.WriteRaw("\n")
+	adapter.stream.Flush()
+	return adapter.stream.Error
+}
+
+// SetIndent set the indention. Prefix is not supported
+func (adapter *Encoder) SetIndent(prefix, indent string) {
+	config := adapter.stream.cfg.configBeforeFrozen
+	config.IndentionStep = len(indent)
+	adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions)
+}
+
+// SetEscapeHTML escape html by default, set to false to disable
+func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) {
+	config := adapter.stream.cfg.configBeforeFrozen
+	config.EscapeHTML = escapeHTML
+	adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions)
+}
+
+// Valid reports whether data is a valid JSON encoding.
+func Valid(data []byte) bool {
+	return ConfigDefault.Valid(data)
+}

+ 321 - 0
vendor/github.com/json-iterator/go/any.go

@@ -0,0 +1,321 @@
+package jsoniter
+
+import (
+	"errors"
+	"fmt"
+	"github.com/modern-go/reflect2"
+	"io"
+	"reflect"
+	"strconv"
+	"unsafe"
+)
+
+// Any generic object representation.
+// The lazy json implementation holds []byte and parse lazily.
+type Any interface {
+	LastError() error
+	ValueType() ValueType
+	MustBeValid() Any
+	ToBool() bool
+	ToInt() int
+	ToInt32() int32
+	ToInt64() int64
+	ToUint() uint
+	ToUint32() uint32
+	ToUint64() uint64
+	ToFloat32() float32
+	ToFloat64() float64
+	ToString() string
+	ToVal(val interface{})
+	Get(path ...interface{}) Any
+	Size() int
+	Keys() []string
+	GetInterface() interface{}
+	WriteTo(stream *Stream)
+}
+
+type baseAny struct{}
+
+func (any *baseAny) Get(path ...interface{}) Any {
+	return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
+}
+
+func (any *baseAny) Size() int {
+	return 0
+}
+
+func (any *baseAny) Keys() []string {
+	return []string{}
+}
+
+func (any *baseAny) ToVal(obj interface{}) {
+	panic("not implemented")
+}
+
+// WrapInt32 turn int32 into Any interface
+func WrapInt32(val int32) Any {
+	return &int32Any{baseAny{}, val}
+}
+
+// WrapInt64 turn int64 into Any interface
+func WrapInt64(val int64) Any {
+	return &int64Any{baseAny{}, val}
+}
+
+// WrapUint32 turn uint32 into Any interface
+func WrapUint32(val uint32) Any {
+	return &uint32Any{baseAny{}, val}
+}
+
+// WrapUint64 turn uint64 into Any interface
+func WrapUint64(val uint64) Any {
+	return &uint64Any{baseAny{}, val}
+}
+
+// WrapFloat64 turn float64 into Any interface
+func WrapFloat64(val float64) Any {
+	return &floatAny{baseAny{}, val}
+}
+
+// WrapString turn string into Any interface
+func WrapString(val string) Any {
+	return &stringAny{baseAny{}, val}
+}
+
+// Wrap turn a go object into Any interface
+func Wrap(val interface{}) Any {
+	if val == nil {
+		return &nilAny{}
+	}
+	asAny, isAny := val.(Any)
+	if isAny {
+		return asAny
+	}
+	typ := reflect2.TypeOf(val)
+	switch typ.Kind() {
+	case reflect.Slice:
+		return wrapArray(val)
+	case reflect.Struct:
+		return wrapStruct(val)
+	case reflect.Map:
+		return wrapMap(val)
+	case reflect.String:
+		return WrapString(val.(string))
+	case reflect.Int:
+		if strconv.IntSize == 32 {
+			return WrapInt32(int32(val.(int)))
+		}
+		return WrapInt64(int64(val.(int)))
+	case reflect.Int8:
+		return WrapInt32(int32(val.(int8)))
+	case reflect.Int16:
+		return WrapInt32(int32(val.(int16)))
+	case reflect.Int32:
+		return WrapInt32(val.(int32))
+	case reflect.Int64:
+		return WrapInt64(val.(int64))
+	case reflect.Uint:
+		if strconv.IntSize == 32 {
+			return WrapUint32(uint32(val.(uint)))
+		}
+		return WrapUint64(uint64(val.(uint)))
+	case reflect.Uintptr:
+		if ptrSize == 32 {
+			return WrapUint32(uint32(val.(uintptr)))
+		}
+		return WrapUint64(uint64(val.(uintptr)))
+	case reflect.Uint8:
+		return WrapUint32(uint32(val.(uint8)))
+	case reflect.Uint16:
+		return WrapUint32(uint32(val.(uint16)))
+	case reflect.Uint32:
+		return WrapUint32(uint32(val.(uint32)))
+	case reflect.Uint64:
+		return WrapUint64(val.(uint64))
+	case reflect.Float32:
+		return WrapFloat64(float64(val.(float32)))
+	case reflect.Float64:
+		return WrapFloat64(val.(float64))
+	case reflect.Bool:
+		if val.(bool) == true {
+			return &trueAny{}
+		}
+		return &falseAny{}
+	}
+	return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)}
+}
+
+// ReadAny read next JSON element as an Any object. It is a better json.RawMessage.
+func (iter *Iterator) ReadAny() Any {
+	return iter.readAny()
+}
+
+func (iter *Iterator) readAny() Any {
+	c := iter.nextToken()
+	switch c {
+	case '"':
+		iter.unreadByte()
+		return &stringAny{baseAny{}, iter.ReadString()}
+	case 'n':
+		iter.skipThreeBytes('u', 'l', 'l') // null
+		return &nilAny{}
+	case 't':
+		iter.skipThreeBytes('r', 'u', 'e') // true
+		return &trueAny{}
+	case 'f':
+		iter.skipFourBytes('a', 'l', 's', 'e') // false
+		return &falseAny{}
+	case '{':
+		return iter.readObjectAny()
+	case '[':
+		return iter.readArrayAny()
+	case '-':
+		return iter.readNumberAny(false)
+	case 0:
+		return &invalidAny{baseAny{}, errors.New("input is empty")}
+	default:
+		return iter.readNumberAny(true)
+	}
+}
+
+func (iter *Iterator) readNumberAny(positive bool) Any {
+	iter.startCapture(iter.head - 1)
+	iter.skipNumber()
+	lazyBuf := iter.stopCapture()
+	return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
+}
+
+func (iter *Iterator) readObjectAny() Any {
+	iter.startCapture(iter.head - 1)
+	iter.skipObject()
+	lazyBuf := iter.stopCapture()
+	return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
+}
+
+func (iter *Iterator) readArrayAny() Any {
+	iter.startCapture(iter.head - 1)
+	iter.skipArray()
+	lazyBuf := iter.stopCapture()
+	return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
+}
+
+func locateObjectField(iter *Iterator, target string) []byte {
+	var found []byte
+	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
+		if field == target {
+			found = iter.SkipAndReturnBytes()
+			return false
+		}
+		iter.Skip()
+		return true
+	})
+	return found
+}
+
+func locateArrayElement(iter *Iterator, target int) []byte {
+	var found []byte
+	n := 0
+	iter.ReadArrayCB(func(iter *Iterator) bool {
+		if n == target {
+			found = iter.SkipAndReturnBytes()
+			return false
+		}
+		iter.Skip()
+		n++
+		return true
+	})
+	return found
+}
+
+func locatePath(iter *Iterator, path []interface{}) Any {
+	for i, pathKeyObj := range path {
+		switch pathKey := pathKeyObj.(type) {
+		case string:
+			valueBytes := locateObjectField(iter, pathKey)
+			if valueBytes == nil {
+				return newInvalidAny(path[i:])
+			}
+			iter.ResetBytes(valueBytes)
+		case int:
+			valueBytes := locateArrayElement(iter, pathKey)
+			if valueBytes == nil {
+				return newInvalidAny(path[i:])
+			}
+			iter.ResetBytes(valueBytes)
+		case int32:
+			if '*' == pathKey {
+				return iter.readAny().Get(path[i:]...)
+			}
+			return newInvalidAny(path[i:])
+		default:
+			return newInvalidAny(path[i:])
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		return &invalidAny{baseAny{}, iter.Error}
+	}
+	return iter.readAny()
+}
+
+var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem()
+
+func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder {
+	if typ == anyType {
+		return &directAnyCodec{}
+	}
+	if typ.Implements(anyType) {
+		return &anyCodec{
+			valType: typ,
+		}
+	}
+	return nil
+}
+
+func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder {
+	if typ == anyType {
+		return &directAnyCodec{}
+	}
+	if typ.Implements(anyType) {
+		return &anyCodec{
+			valType: typ,
+		}
+	}
+	return nil
+}
+
+type anyCodec struct {
+	valType reflect2.Type
+}
+
+func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	panic("not implemented")
+}
+
+func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	obj := codec.valType.UnsafeIndirect(ptr)
+	any := obj.(Any)
+	any.WriteTo(stream)
+}
+
+func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	obj := codec.valType.UnsafeIndirect(ptr)
+	any := obj.(Any)
+	return any.Size() == 0
+}
+
+type directAnyCodec struct {
+}
+
+func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*(*Any)(ptr) = iter.readAny()
+}
+
+func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	any := *(*Any)(ptr)
+	any.WriteTo(stream)
+}
+
+func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	any := *(*Any)(ptr)
+	return any.Size() == 0
+}

+ 278 - 0
vendor/github.com/json-iterator/go/any_array.go

@@ -0,0 +1,278 @@
+package jsoniter
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type arrayLazyAny struct {
+	baseAny
+	cfg *frozenConfig
+	buf []byte
+	err error
+}
+
+func (any *arrayLazyAny) ValueType() ValueType {
+	return ArrayValue
+}
+
+func (any *arrayLazyAny) MustBeValid() Any {
+	return any
+}
+
+func (any *arrayLazyAny) LastError() error {
+	return any.err
+}
+
+func (any *arrayLazyAny) ToBool() bool {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	return iter.ReadArray()
+}
+
+func (any *arrayLazyAny) ToInt() int {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToInt32() int32 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToInt64() int64 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToUint() uint {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToUint32() uint32 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToUint64() uint64 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToFloat32() float32 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToFloat64() float64 {
+	if any.ToBool() {
+		return 1
+	}
+	return 0
+}
+
+func (any *arrayLazyAny) ToString() string {
+	return *(*string)(unsafe.Pointer(&any.buf))
+}
+
+func (any *arrayLazyAny) ToVal(val interface{}) {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	iter.ReadVal(val)
+}
+
+func (any *arrayLazyAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	switch firstPath := path[0].(type) {
+	case int:
+		iter := any.cfg.BorrowIterator(any.buf)
+		defer any.cfg.ReturnIterator(iter)
+		valueBytes := locateArrayElement(iter, firstPath)
+		if valueBytes == nil {
+			return newInvalidAny(path)
+		}
+		iter.ResetBytes(valueBytes)
+		return locatePath(iter, path[1:])
+	case int32:
+		if '*' == firstPath {
+			iter := any.cfg.BorrowIterator(any.buf)
+			defer any.cfg.ReturnIterator(iter)
+			arr := make([]Any, 0)
+			iter.ReadArrayCB(func(iter *Iterator) bool {
+				found := iter.readAny().Get(path[1:]...)
+				if found.ValueType() != InvalidValue {
+					arr = append(arr, found)
+				}
+				return true
+			})
+			return wrapArray(arr)
+		}
+		return newInvalidAny(path)
+	default:
+		return newInvalidAny(path)
+	}
+}
+
+func (any *arrayLazyAny) Size() int {
+	size := 0
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	iter.ReadArrayCB(func(iter *Iterator) bool {
+		size++
+		iter.Skip()
+		return true
+	})
+	return size
+}
+
+func (any *arrayLazyAny) WriteTo(stream *Stream) {
+	stream.Write(any.buf)
+}
+
+func (any *arrayLazyAny) GetInterface() interface{} {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	return iter.Read()
+}
+
+type arrayAny struct {
+	baseAny
+	val reflect.Value
+}
+
+func wrapArray(val interface{}) *arrayAny {
+	return &arrayAny{baseAny{}, reflect.ValueOf(val)}
+}
+
+func (any *arrayAny) ValueType() ValueType {
+	return ArrayValue
+}
+
+func (any *arrayAny) MustBeValid() Any {
+	return any
+}
+
+func (any *arrayAny) LastError() error {
+	return nil
+}
+
+func (any *arrayAny) ToBool() bool {
+	return any.val.Len() != 0
+}
+
+func (any *arrayAny) ToInt() int {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToInt32() int32 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToInt64() int64 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToUint() uint {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToUint32() uint32 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToUint64() uint64 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToFloat32() float32 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToFloat64() float64 {
+	if any.val.Len() == 0 {
+		return 0
+	}
+	return 1
+}
+
+func (any *arrayAny) ToString() string {
+	str, _ := MarshalToString(any.val.Interface())
+	return str
+}
+
+func (any *arrayAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	switch firstPath := path[0].(type) {
+	case int:
+		if firstPath < 0 || firstPath >= any.val.Len() {
+			return newInvalidAny(path)
+		}
+		return Wrap(any.val.Index(firstPath).Interface())
+	case int32:
+		if '*' == firstPath {
+			mappedAll := make([]Any, 0)
+			for i := 0; i < any.val.Len(); i++ {
+				mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...)
+				if mapped.ValueType() != InvalidValue {
+					mappedAll = append(mappedAll, mapped)
+				}
+			}
+			return wrapArray(mappedAll)
+		}
+		return newInvalidAny(path)
+	default:
+		return newInvalidAny(path)
+	}
+}
+
+func (any *arrayAny) Size() int {
+	return any.val.Len()
+}
+
+func (any *arrayAny) WriteTo(stream *Stream) {
+	stream.WriteVal(any.val)
+}
+
+func (any *arrayAny) GetInterface() interface{} {
+	return any.val.Interface()
+}

+ 137 - 0
vendor/github.com/json-iterator/go/any_bool.go

@@ -0,0 +1,137 @@
+package jsoniter
+
+type trueAny struct {
+	baseAny
+}
+
+func (any *trueAny) LastError() error {
+	return nil
+}
+
+func (any *trueAny) ToBool() bool {
+	return true
+}
+
+func (any *trueAny) ToInt() int {
+	return 1
+}
+
+func (any *trueAny) ToInt32() int32 {
+	return 1
+}
+
+func (any *trueAny) ToInt64() int64 {
+	return 1
+}
+
+func (any *trueAny) ToUint() uint {
+	return 1
+}
+
+func (any *trueAny) ToUint32() uint32 {
+	return 1
+}
+
+func (any *trueAny) ToUint64() uint64 {
+	return 1
+}
+
+func (any *trueAny) ToFloat32() float32 {
+	return 1
+}
+
+func (any *trueAny) ToFloat64() float64 {
+	return 1
+}
+
+func (any *trueAny) ToString() string {
+	return "true"
+}
+
+func (any *trueAny) WriteTo(stream *Stream) {
+	stream.WriteTrue()
+}
+
+func (any *trueAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *trueAny) GetInterface() interface{} {
+	return true
+}
+
+func (any *trueAny) ValueType() ValueType {
+	return BoolValue
+}
+
+func (any *trueAny) MustBeValid() Any {
+	return any
+}
+
+type falseAny struct {
+	baseAny
+}
+
+func (any *falseAny) LastError() error {
+	return nil
+}
+
+func (any *falseAny) ToBool() bool {
+	return false
+}
+
+func (any *falseAny) ToInt() int {
+	return 0
+}
+
+func (any *falseAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *falseAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *falseAny) ToUint() uint {
+	return 0
+}
+
+func (any *falseAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *falseAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *falseAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *falseAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *falseAny) ToString() string {
+	return "false"
+}
+
+func (any *falseAny) WriteTo(stream *Stream) {
+	stream.WriteFalse()
+}
+
+func (any *falseAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *falseAny) GetInterface() interface{} {
+	return false
+}
+
+func (any *falseAny) ValueType() ValueType {
+	return BoolValue
+}
+
+func (any *falseAny) MustBeValid() Any {
+	return any
+}

+ 83 - 0
vendor/github.com/json-iterator/go/any_float.go

@@ -0,0 +1,83 @@
+package jsoniter
+
+import (
+	"strconv"
+)
+
+type floatAny struct {
+	baseAny
+	val float64
+}
+
+func (any *floatAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *floatAny) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *floatAny) MustBeValid() Any {
+	return any
+}
+
+func (any *floatAny) LastError() error {
+	return nil
+}
+
+func (any *floatAny) ToBool() bool {
+	return any.ToFloat64() != 0
+}
+
+func (any *floatAny) ToInt() int {
+	return int(any.val)
+}
+
+func (any *floatAny) ToInt32() int32 {
+	return int32(any.val)
+}
+
+func (any *floatAny) ToInt64() int64 {
+	return int64(any.val)
+}
+
+func (any *floatAny) ToUint() uint {
+	if any.val > 0 {
+		return uint(any.val)
+	}
+	return 0
+}
+
+func (any *floatAny) ToUint32() uint32 {
+	if any.val > 0 {
+		return uint32(any.val)
+	}
+	return 0
+}
+
+func (any *floatAny) ToUint64() uint64 {
+	if any.val > 0 {
+		return uint64(any.val)
+	}
+	return 0
+}
+
+func (any *floatAny) ToFloat32() float32 {
+	return float32(any.val)
+}
+
+func (any *floatAny) ToFloat64() float64 {
+	return any.val
+}
+
+func (any *floatAny) ToString() string {
+	return strconv.FormatFloat(any.val, 'E', -1, 64)
+}
+
+func (any *floatAny) WriteTo(stream *Stream) {
+	stream.WriteFloat64(any.val)
+}
+
+func (any *floatAny) GetInterface() interface{} {
+	return any.val
+}

+ 74 - 0
vendor/github.com/json-iterator/go/any_int32.go

@@ -0,0 +1,74 @@
+package jsoniter
+
+import (
+	"strconv"
+)
+
+type int32Any struct {
+	baseAny
+	val int32
+}
+
+func (any *int32Any) LastError() error {
+	return nil
+}
+
+func (any *int32Any) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *int32Any) MustBeValid() Any {
+	return any
+}
+
+func (any *int32Any) ToBool() bool {
+	return any.val != 0
+}
+
+func (any *int32Any) ToInt() int {
+	return int(any.val)
+}
+
+func (any *int32Any) ToInt32() int32 {
+	return any.val
+}
+
+func (any *int32Any) ToInt64() int64 {
+	return int64(any.val)
+}
+
+func (any *int32Any) ToUint() uint {
+	return uint(any.val)
+}
+
+func (any *int32Any) ToUint32() uint32 {
+	return uint32(any.val)
+}
+
+func (any *int32Any) ToUint64() uint64 {
+	return uint64(any.val)
+}
+
+func (any *int32Any) ToFloat32() float32 {
+	return float32(any.val)
+}
+
+func (any *int32Any) ToFloat64() float64 {
+	return float64(any.val)
+}
+
+func (any *int32Any) ToString() string {
+	return strconv.FormatInt(int64(any.val), 10)
+}
+
+func (any *int32Any) WriteTo(stream *Stream) {
+	stream.WriteInt32(any.val)
+}
+
+func (any *int32Any) Parse() *Iterator {
+	return nil
+}
+
+func (any *int32Any) GetInterface() interface{} {
+	return any.val
+}

+ 74 - 0
vendor/github.com/json-iterator/go/any_int64.go

@@ -0,0 +1,74 @@
+package jsoniter
+
+import (
+	"strconv"
+)
+
+type int64Any struct {
+	baseAny
+	val int64
+}
+
+func (any *int64Any) LastError() error {
+	return nil
+}
+
+func (any *int64Any) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *int64Any) MustBeValid() Any {
+	return any
+}
+
+func (any *int64Any) ToBool() bool {
+	return any.val != 0
+}
+
+func (any *int64Any) ToInt() int {
+	return int(any.val)
+}
+
+func (any *int64Any) ToInt32() int32 {
+	return int32(any.val)
+}
+
+func (any *int64Any) ToInt64() int64 {
+	return any.val
+}
+
+func (any *int64Any) ToUint() uint {
+	return uint(any.val)
+}
+
+func (any *int64Any) ToUint32() uint32 {
+	return uint32(any.val)
+}
+
+func (any *int64Any) ToUint64() uint64 {
+	return uint64(any.val)
+}
+
+func (any *int64Any) ToFloat32() float32 {
+	return float32(any.val)
+}
+
+func (any *int64Any) ToFloat64() float64 {
+	return float64(any.val)
+}
+
+func (any *int64Any) ToString() string {
+	return strconv.FormatInt(any.val, 10)
+}
+
+func (any *int64Any) WriteTo(stream *Stream) {
+	stream.WriteInt64(any.val)
+}
+
+func (any *int64Any) Parse() *Iterator {
+	return nil
+}
+
+func (any *int64Any) GetInterface() interface{} {
+	return any.val
+}

+ 82 - 0
vendor/github.com/json-iterator/go/any_invalid.go

@@ -0,0 +1,82 @@
+package jsoniter
+
+import "fmt"
+
+type invalidAny struct {
+	baseAny
+	err error
+}
+
+func newInvalidAny(path []interface{}) *invalidAny {
+	return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)}
+}
+
+func (any *invalidAny) LastError() error {
+	return any.err
+}
+
+func (any *invalidAny) ValueType() ValueType {
+	return InvalidValue
+}
+
+func (any *invalidAny) MustBeValid() Any {
+	panic(any.err)
+}
+
+func (any *invalidAny) ToBool() bool {
+	return false
+}
+
+func (any *invalidAny) ToInt() int {
+	return 0
+}
+
+func (any *invalidAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *invalidAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *invalidAny) ToUint() uint {
+	return 0
+}
+
+func (any *invalidAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *invalidAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *invalidAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *invalidAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *invalidAny) ToString() string {
+	return ""
+}
+
+func (any *invalidAny) WriteTo(stream *Stream) {
+}
+
+func (any *invalidAny) Get(path ...interface{}) Any {
+	if any.err == nil {
+		return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)}
+	}
+	return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)}
+}
+
+func (any *invalidAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *invalidAny) GetInterface() interface{} {
+	return nil
+}

+ 69 - 0
vendor/github.com/json-iterator/go/any_nil.go

@@ -0,0 +1,69 @@
+package jsoniter
+
+type nilAny struct {
+	baseAny
+}
+
+func (any *nilAny) LastError() error {
+	return nil
+}
+
+func (any *nilAny) ValueType() ValueType {
+	return NilValue
+}
+
+func (any *nilAny) MustBeValid() Any {
+	return any
+}
+
+func (any *nilAny) ToBool() bool {
+	return false
+}
+
+func (any *nilAny) ToInt() int {
+	return 0
+}
+
+func (any *nilAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *nilAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *nilAny) ToUint() uint {
+	return 0
+}
+
+func (any *nilAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *nilAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *nilAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *nilAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *nilAny) ToString() string {
+	return ""
+}
+
+func (any *nilAny) WriteTo(stream *Stream) {
+	stream.WriteNil()
+}
+
+func (any *nilAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *nilAny) GetInterface() interface{} {
+	return nil
+}

+ 123 - 0
vendor/github.com/json-iterator/go/any_number.go

@@ -0,0 +1,123 @@
+package jsoniter
+
+import (
+	"io"
+	"unsafe"
+)
+
+type numberLazyAny struct {
+	baseAny
+	cfg *frozenConfig
+	buf []byte
+	err error
+}
+
+func (any *numberLazyAny) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *numberLazyAny) MustBeValid() Any {
+	return any
+}
+
+func (any *numberLazyAny) LastError() error {
+	return any.err
+}
+
+func (any *numberLazyAny) ToBool() bool {
+	return any.ToFloat64() != 0
+}
+
+func (any *numberLazyAny) ToInt() int {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	val := iter.ReadInt()
+	if iter.Error != nil && iter.Error != io.EOF {
+		any.err = iter.Error
+	}
+	return val
+}
+
+func (any *numberLazyAny) ToInt32() int32 {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	val := iter.ReadInt32()
+	if iter.Error != nil && iter.Error != io.EOF {
+		any.err = iter.Error
+	}
+	return val
+}
+
+func (any *numberLazyAny) ToInt64() int64 {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	val := iter.ReadInt64()
+	if iter.Error != nil && iter.Error != io.EOF {
+		any.err = iter.Error
+	}
+	return val
+}
+
+func (any *numberLazyAny) ToUint() uint {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	val := iter.ReadUint()
+	if iter.Error != nil && iter.Error != io.EOF {
+		any.err = iter.Error
+	}
+	return val
+}
+
+func (any *numberLazyAny) ToUint32() uint32 {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	val := iter.ReadUint32()
+	if iter.Error != nil && iter.Error != io.EOF {
+		any.err = iter.Error
+	}
+	return val
+}
+
+func (any *numberLazyAny) ToUint64() uint64 {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	val := iter.ReadUint64()
+	if iter.Error != nil && iter.Error != io.EOF {
+		any.err = iter.Error
+	}
+	return val
+}
+
+func (any *numberLazyAny) ToFloat32() float32 {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	val := iter.ReadFloat32()
+	if iter.Error != nil && iter.Error != io.EOF {
+		any.err = iter.Error
+	}
+	return val
+}
+
+func (any *numberLazyAny) ToFloat64() float64 {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	val := iter.ReadFloat64()
+	if iter.Error != nil && iter.Error != io.EOF {
+		any.err = iter.Error
+	}
+	return val
+}
+
+func (any *numberLazyAny) ToString() string {
+	return *(*string)(unsafe.Pointer(&any.buf))
+}
+
+func (any *numberLazyAny) WriteTo(stream *Stream) {
+	stream.Write(any.buf)
+}
+
+func (any *numberLazyAny) GetInterface() interface{} {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	return iter.Read()
+}

+ 374 - 0
vendor/github.com/json-iterator/go/any_object.go

@@ -0,0 +1,374 @@
+package jsoniter
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type objectLazyAny struct {
+	baseAny
+	cfg *frozenConfig
+	buf []byte
+	err error
+}
+
+func (any *objectLazyAny) ValueType() ValueType {
+	return ObjectValue
+}
+
+func (any *objectLazyAny) MustBeValid() Any {
+	return any
+}
+
+func (any *objectLazyAny) LastError() error {
+	return any.err
+}
+
+func (any *objectLazyAny) ToBool() bool {
+	return true
+}
+
+func (any *objectLazyAny) ToInt() int {
+	return 0
+}
+
+func (any *objectLazyAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *objectLazyAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *objectLazyAny) ToUint() uint {
+	return 0
+}
+
+func (any *objectLazyAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *objectLazyAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *objectLazyAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *objectLazyAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *objectLazyAny) ToString() string {
+	return *(*string)(unsafe.Pointer(&any.buf))
+}
+
+func (any *objectLazyAny) ToVal(obj interface{}) {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	iter.ReadVal(obj)
+}
+
+func (any *objectLazyAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	switch firstPath := path[0].(type) {
+	case string:
+		iter := any.cfg.BorrowIterator(any.buf)
+		defer any.cfg.ReturnIterator(iter)
+		valueBytes := locateObjectField(iter, firstPath)
+		if valueBytes == nil {
+			return newInvalidAny(path)
+		}
+		iter.ResetBytes(valueBytes)
+		return locatePath(iter, path[1:])
+	case int32:
+		if '*' == firstPath {
+			mappedAll := map[string]Any{}
+			iter := any.cfg.BorrowIterator(any.buf)
+			defer any.cfg.ReturnIterator(iter)
+			iter.ReadMapCB(func(iter *Iterator, field string) bool {
+				mapped := locatePath(iter, path[1:])
+				if mapped.ValueType() != InvalidValue {
+					mappedAll[field] = mapped
+				}
+				return true
+			})
+			return wrapMap(mappedAll)
+		}
+		return newInvalidAny(path)
+	default:
+		return newInvalidAny(path)
+	}
+}
+
+func (any *objectLazyAny) Keys() []string {
+	keys := []string{}
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	iter.ReadMapCB(func(iter *Iterator, field string) bool {
+		iter.Skip()
+		keys = append(keys, field)
+		return true
+	})
+	return keys
+}
+
+func (any *objectLazyAny) Size() int {
+	size := 0
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
+		iter.Skip()
+		size++
+		return true
+	})
+	return size
+}
+
+func (any *objectLazyAny) WriteTo(stream *Stream) {
+	stream.Write(any.buf)
+}
+
+func (any *objectLazyAny) GetInterface() interface{} {
+	iter := any.cfg.BorrowIterator(any.buf)
+	defer any.cfg.ReturnIterator(iter)
+	return iter.Read()
+}
+
+type objectAny struct {
+	baseAny
+	err error
+	val reflect.Value
+}
+
+func wrapStruct(val interface{}) *objectAny {
+	return &objectAny{baseAny{}, nil, reflect.ValueOf(val)}
+}
+
+func (any *objectAny) ValueType() ValueType {
+	return ObjectValue
+}
+
+func (any *objectAny) MustBeValid() Any {
+	return any
+}
+
+func (any *objectAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *objectAny) LastError() error {
+	return any.err
+}
+
+func (any *objectAny) ToBool() bool {
+	return any.val.NumField() != 0
+}
+
+func (any *objectAny) ToInt() int {
+	return 0
+}
+
+func (any *objectAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *objectAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *objectAny) ToUint() uint {
+	return 0
+}
+
+func (any *objectAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *objectAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *objectAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *objectAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *objectAny) ToString() string {
+	str, err := MarshalToString(any.val.Interface())
+	any.err = err
+	return str
+}
+
+func (any *objectAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	switch firstPath := path[0].(type) {
+	case string:
+		field := any.val.FieldByName(firstPath)
+		if !field.IsValid() {
+			return newInvalidAny(path)
+		}
+		return Wrap(field.Interface())
+	case int32:
+		if '*' == firstPath {
+			mappedAll := map[string]Any{}
+			for i := 0; i < any.val.NumField(); i++ {
+				field := any.val.Field(i)
+				if field.CanInterface() {
+					mapped := Wrap(field.Interface()).Get(path[1:]...)
+					if mapped.ValueType() != InvalidValue {
+						mappedAll[any.val.Type().Field(i).Name] = mapped
+					}
+				}
+			}
+			return wrapMap(mappedAll)
+		}
+		return newInvalidAny(path)
+	default:
+		return newInvalidAny(path)
+	}
+}
+
+func (any *objectAny) Keys() []string {
+	keys := make([]string, 0, any.val.NumField())
+	for i := 0; i < any.val.NumField(); i++ {
+		keys = append(keys, any.val.Type().Field(i).Name)
+	}
+	return keys
+}
+
+func (any *objectAny) Size() int {
+	return any.val.NumField()
+}
+
+func (any *objectAny) WriteTo(stream *Stream) {
+	stream.WriteVal(any.val)
+}
+
+func (any *objectAny) GetInterface() interface{} {
+	return any.val.Interface()
+}
+
+type mapAny struct {
+	baseAny
+	err error
+	val reflect.Value
+}
+
+func wrapMap(val interface{}) *mapAny {
+	return &mapAny{baseAny{}, nil, reflect.ValueOf(val)}
+}
+
+func (any *mapAny) ValueType() ValueType {
+	return ObjectValue
+}
+
+func (any *mapAny) MustBeValid() Any {
+	return any
+}
+
+func (any *mapAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *mapAny) LastError() error {
+	return any.err
+}
+
+func (any *mapAny) ToBool() bool {
+	return true
+}
+
+func (any *mapAny) ToInt() int {
+	return 0
+}
+
+func (any *mapAny) ToInt32() int32 {
+	return 0
+}
+
+func (any *mapAny) ToInt64() int64 {
+	return 0
+}
+
+func (any *mapAny) ToUint() uint {
+	return 0
+}
+
+func (any *mapAny) ToUint32() uint32 {
+	return 0
+}
+
+func (any *mapAny) ToUint64() uint64 {
+	return 0
+}
+
+func (any *mapAny) ToFloat32() float32 {
+	return 0
+}
+
+func (any *mapAny) ToFloat64() float64 {
+	return 0
+}
+
+func (any *mapAny) ToString() string {
+	str, err := MarshalToString(any.val.Interface())
+	any.err = err
+	return str
+}
+
+func (any *mapAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	switch firstPath := path[0].(type) {
+	case int32:
+		if '*' == firstPath {
+			mappedAll := map[string]Any{}
+			for _, key := range any.val.MapKeys() {
+				keyAsStr := key.String()
+				element := Wrap(any.val.MapIndex(key).Interface())
+				mapped := element.Get(path[1:]...)
+				if mapped.ValueType() != InvalidValue {
+					mappedAll[keyAsStr] = mapped
+				}
+			}
+			return wrapMap(mappedAll)
+		}
+		return newInvalidAny(path)
+	default:
+		value := any.val.MapIndex(reflect.ValueOf(firstPath))
+		if !value.IsValid() {
+			return newInvalidAny(path)
+		}
+		return Wrap(value.Interface())
+	}
+}
+
+func (any *mapAny) Keys() []string {
+	keys := make([]string, 0, any.val.Len())
+	for _, key := range any.val.MapKeys() {
+		keys = append(keys, key.String())
+	}
+	return keys
+}
+
+func (any *mapAny) Size() int {
+	return any.val.Len()
+}
+
+func (any *mapAny) WriteTo(stream *Stream) {
+	stream.WriteVal(any.val)
+}
+
+func (any *mapAny) GetInterface() interface{} {
+	return any.val.Interface()
+}

+ 166 - 0
vendor/github.com/json-iterator/go/any_str.go

@@ -0,0 +1,166 @@
+package jsoniter
+
+import (
+	"fmt"
+	"strconv"
+)
+
+type stringAny struct {
+	baseAny
+	val string
+}
+
+func (any *stringAny) Get(path ...interface{}) Any {
+	if len(path) == 0 {
+		return any
+	}
+	return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
+}
+
+func (any *stringAny) Parse() *Iterator {
+	return nil
+}
+
+func (any *stringAny) ValueType() ValueType {
+	return StringValue
+}
+
+func (any *stringAny) MustBeValid() Any {
+	return any
+}
+
+func (any *stringAny) LastError() error {
+	return nil
+}
+
+func (any *stringAny) ToBool() bool {
+	str := any.ToString()
+	if str == "0" {
+		return false
+	}
+	for _, c := range str {
+		switch c {
+		case ' ', '\n', '\r', '\t':
+		default:
+			return true
+		}
+	}
+	return false
+}
+
+func (any *stringAny) ToInt() int {
+	return int(any.ToInt64())
+
+}
+
+func (any *stringAny) ToInt32() int32 {
+	return int32(any.ToInt64())
+}
+
+func (any *stringAny) ToInt64() int64 {
+	if any.val == "" {
+		return 0
+	}
+
+	flag := 1
+	startPos := 0
+	endPos := 0
+	if any.val[0] == '+' || any.val[0] == '-' {
+		startPos = 1
+	}
+
+	if any.val[0] == '-' {
+		flag = -1
+	}
+
+	for i := startPos; i < len(any.val); i++ {
+		if any.val[i] >= '0' && any.val[i] <= '9' {
+			endPos = i + 1
+		} else {
+			break
+		}
+	}
+	parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64)
+	return int64(flag) * parsed
+}
+
+func (any *stringAny) ToUint() uint {
+	return uint(any.ToUint64())
+}
+
+func (any *stringAny) ToUint32() uint32 {
+	return uint32(any.ToUint64())
+}
+
+func (any *stringAny) ToUint64() uint64 {
+	if any.val == "" {
+		return 0
+	}
+
+	startPos := 0
+	endPos := 0
+
+	if any.val[0] == '-' {
+		return 0
+	}
+	if any.val[0] == '+' {
+		startPos = 1
+	}
+
+	for i := startPos; i < len(any.val); i++ {
+		if any.val[i] >= '0' && any.val[i] <= '9' {
+			endPos = i + 1
+		} else {
+			break
+		}
+	}
+	parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64)
+	return parsed
+}
+
+func (any *stringAny) ToFloat32() float32 {
+	return float32(any.ToFloat64())
+}
+
+func (any *stringAny) ToFloat64() float64 {
+	if len(any.val) == 0 {
+		return 0
+	}
+
+	// first char invalid
+	if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') {
+		return 0
+	}
+
+	// extract valid num expression from string
+	// eg 123true => 123, -12.12xxa => -12.12
+	endPos := 1
+	for i := 1; i < len(any.val); i++ {
+		if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' {
+			endPos = i + 1
+			continue
+		}
+
+		// end position is the first char which is not digit
+		if any.val[i] >= '0' && any.val[i] <= '9' {
+			endPos = i + 1
+		} else {
+			endPos = i
+			break
+		}
+	}
+	parsed, _ := strconv.ParseFloat(any.val[:endPos], 64)
+	return parsed
+}
+
+func (any *stringAny) ToString() string {
+	return any.val
+}
+
+func (any *stringAny) WriteTo(stream *Stream) {
+	stream.WriteString(any.val)
+}
+
+func (any *stringAny) GetInterface() interface{} {
+	return any.val
+}

+ 74 - 0
vendor/github.com/json-iterator/go/any_uint32.go

@@ -0,0 +1,74 @@
+package jsoniter
+
+import (
+	"strconv"
+)
+
+type uint32Any struct {
+	baseAny
+	val uint32
+}
+
+func (any *uint32Any) LastError() error {
+	return nil
+}
+
+func (any *uint32Any) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *uint32Any) MustBeValid() Any {
+	return any
+}
+
+func (any *uint32Any) ToBool() bool {
+	return any.val != 0
+}
+
+func (any *uint32Any) ToInt() int {
+	return int(any.val)
+}
+
+func (any *uint32Any) ToInt32() int32 {
+	return int32(any.val)
+}
+
+func (any *uint32Any) ToInt64() int64 {
+	return int64(any.val)
+}
+
+func (any *uint32Any) ToUint() uint {
+	return uint(any.val)
+}
+
+func (any *uint32Any) ToUint32() uint32 {
+	return any.val
+}
+
+func (any *uint32Any) ToUint64() uint64 {
+	return uint64(any.val)
+}
+
+func (any *uint32Any) ToFloat32() float32 {
+	return float32(any.val)
+}
+
+func (any *uint32Any) ToFloat64() float64 {
+	return float64(any.val)
+}
+
+func (any *uint32Any) ToString() string {
+	return strconv.FormatInt(int64(any.val), 10)
+}
+
+func (any *uint32Any) WriteTo(stream *Stream) {
+	stream.WriteUint32(any.val)
+}
+
+func (any *uint32Any) Parse() *Iterator {
+	return nil
+}
+
+func (any *uint32Any) GetInterface() interface{} {
+	return any.val
+}

+ 74 - 0
vendor/github.com/json-iterator/go/any_uint64.go

@@ -0,0 +1,74 @@
+package jsoniter
+
+import (
+	"strconv"
+)
+
+type uint64Any struct {
+	baseAny
+	val uint64
+}
+
+func (any *uint64Any) LastError() error {
+	return nil
+}
+
+func (any *uint64Any) ValueType() ValueType {
+	return NumberValue
+}
+
+func (any *uint64Any) MustBeValid() Any {
+	return any
+}
+
+func (any *uint64Any) ToBool() bool {
+	return any.val != 0
+}
+
+func (any *uint64Any) ToInt() int {
+	return int(any.val)
+}
+
+func (any *uint64Any) ToInt32() int32 {
+	return int32(any.val)
+}
+
+func (any *uint64Any) ToInt64() int64 {
+	return int64(any.val)
+}
+
+func (any *uint64Any) ToUint() uint {
+	return uint(any.val)
+}
+
+func (any *uint64Any) ToUint32() uint32 {
+	return uint32(any.val)
+}
+
+func (any *uint64Any) ToUint64() uint64 {
+	return any.val
+}
+
+func (any *uint64Any) ToFloat32() float32 {
+	return float32(any.val)
+}
+
+func (any *uint64Any) ToFloat64() float64 {
+	return float64(any.val)
+}
+
+func (any *uint64Any) ToString() string {
+	return strconv.FormatUint(any.val, 10)
+}
+
+func (any *uint64Any) WriteTo(stream *Stream) {
+	stream.WriteUint64(any.val)
+}
+
+func (any *uint64Any) Parse() *Iterator {
+	return nil
+}
+
+func (any *uint64Any) GetInterface() interface{} {
+	return any.val
+}

+ 375 - 0
vendor/github.com/json-iterator/go/config.go

@@ -0,0 +1,375 @@
+package jsoniter
+
+import (
+	"encoding/json"
+	"io"
+	"reflect"
+	"sync"
+	"unsafe"
+
+	"github.com/modern-go/concurrent"
+	"github.com/modern-go/reflect2"
+)
+
+// Config customize how the API should behave.
+// The API is created from Config by Froze.
+type Config struct {
+	IndentionStep                 int
+	MarshalFloatWith6Digits       bool
+	EscapeHTML                    bool
+	SortMapKeys                   bool
+	UseNumber                     bool
+	DisallowUnknownFields         bool
+	TagKey                        string
+	OnlyTaggedField               bool
+	ValidateJsonRawMessage        bool
+	ObjectFieldMustBeSimpleString bool
+	CaseSensitive                 bool
+}
+
+// API the public interface of this package.
+// Primary Marshal and Unmarshal.
+type API interface {
+	IteratorPool
+	StreamPool
+	MarshalToString(v interface{}) (string, error)
+	Marshal(v interface{}) ([]byte, error)
+	MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
+	UnmarshalFromString(str string, v interface{}) error
+	Unmarshal(data []byte, v interface{}) error
+	Get(data []byte, path ...interface{}) Any
+	NewEncoder(writer io.Writer) *Encoder
+	NewDecoder(reader io.Reader) *Decoder
+	Valid(data []byte) bool
+	RegisterExtension(extension Extension)
+	DecoderOf(typ reflect2.Type) ValDecoder
+	EncoderOf(typ reflect2.Type) ValEncoder
+}
+
+// ConfigDefault the default API
+var ConfigDefault = Config{
+	EscapeHTML: true,
+}.Froze()
+
+// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior
+var ConfigCompatibleWithStandardLibrary = Config{
+	EscapeHTML:             true,
+	SortMapKeys:            true,
+	ValidateJsonRawMessage: true,
+}.Froze()
+
+// ConfigFastest marshals float with only 6 digits precision
+var ConfigFastest = Config{
+	EscapeHTML:                    false,
+	MarshalFloatWith6Digits:       true, // will lose precession
+	ObjectFieldMustBeSimpleString: true, // do not unescape object field
+}.Froze()
+
+type frozenConfig struct {
+	configBeforeFrozen            Config
+	sortMapKeys                   bool
+	indentionStep                 int
+	objectFieldMustBeSimpleString bool
+	onlyTaggedField               bool
+	disallowUnknownFields         bool
+	decoderCache                  *concurrent.Map
+	encoderCache                  *concurrent.Map
+	encoderExtension              Extension
+	decoderExtension              Extension
+	extraExtensions               []Extension
+	streamPool                    *sync.Pool
+	iteratorPool                  *sync.Pool
+	caseSensitive                 bool
+}
+
+func (cfg *frozenConfig) initCache() {
+	cfg.decoderCache = concurrent.NewMap()
+	cfg.encoderCache = concurrent.NewMap()
+}
+
+func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) {
+	cfg.decoderCache.Store(cacheKey, decoder)
+}
+
+func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) {
+	cfg.encoderCache.Store(cacheKey, encoder)
+}
+
+func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder {
+	decoder, found := cfg.decoderCache.Load(cacheKey)
+	if found {
+		return decoder.(ValDecoder)
+	}
+	return nil
+}
+
+func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder {
+	encoder, found := cfg.encoderCache.Load(cacheKey)
+	if found {
+		return encoder.(ValEncoder)
+	}
+	return nil
+}
+
+var cfgCache = concurrent.NewMap()
+
+func getFrozenConfigFromCache(cfg Config) *frozenConfig {
+	obj, found := cfgCache.Load(cfg)
+	if found {
+		return obj.(*frozenConfig)
+	}
+	return nil
+}
+
+func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
+	cfgCache.Store(cfg, frozenConfig)
+}
+
+// Froze forge API from config
+func (cfg Config) Froze() API {
+	api := &frozenConfig{
+		sortMapKeys:                   cfg.SortMapKeys,
+		indentionStep:                 cfg.IndentionStep,
+		objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString,
+		onlyTaggedField:               cfg.OnlyTaggedField,
+		disallowUnknownFields:         cfg.DisallowUnknownFields,
+		caseSensitive:                 cfg.CaseSensitive,
+	}
+	api.streamPool = &sync.Pool{
+		New: func() interface{} {
+			return NewStream(api, nil, 512)
+		},
+	}
+	api.iteratorPool = &sync.Pool{
+		New: func() interface{} {
+			return NewIterator(api)
+		},
+	}
+	api.initCache()
+	encoderExtension := EncoderExtension{}
+	decoderExtension := DecoderExtension{}
+	if cfg.MarshalFloatWith6Digits {
+		api.marshalFloatWith6Digits(encoderExtension)
+	}
+	if cfg.EscapeHTML {
+		api.escapeHTML(encoderExtension)
+	}
+	if cfg.UseNumber {
+		api.useNumber(decoderExtension)
+	}
+	if cfg.ValidateJsonRawMessage {
+		api.validateJsonRawMessage(encoderExtension)
+	}
+	api.encoderExtension = encoderExtension
+	api.decoderExtension = decoderExtension
+	api.configBeforeFrozen = cfg
+	return api
+}
+
+func (cfg Config) frozeWithCacheReuse(extraExtensions []Extension) *frozenConfig {
+	api := getFrozenConfigFromCache(cfg)
+	if api != nil {
+		return api
+	}
+	api = cfg.Froze().(*frozenConfig)
+	for _, extension := range extraExtensions {
+		api.RegisterExtension(extension)
+	}
+	addFrozenConfigToCache(cfg, api)
+	return api
+}
+
+func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) {
+	encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) {
+		rawMessage := *(*json.RawMessage)(ptr)
+		iter := cfg.BorrowIterator([]byte(rawMessage))
+		iter.Read()
+		if iter.Error != nil {
+			stream.WriteRaw("null")
+		} else {
+			cfg.ReturnIterator(iter)
+			stream.WriteRaw(string(rawMessage))
+		}
+	}, func(ptr unsafe.Pointer) bool {
+		return len(*((*json.RawMessage)(ptr))) == 0
+	}}
+	extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder
+	extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder
+}
+
+func (cfg *frozenConfig) useNumber(extension DecoderExtension) {
+	extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
+		exitingValue := *((*interface{})(ptr))
+		if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr {
+			iter.ReadVal(exitingValue)
+			return
+		}
+		if iter.WhatIsNext() == NumberValue {
+			*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
+		} else {
+			*((*interface{})(ptr)) = iter.Read()
+		}
+	}}
+}
+func (cfg *frozenConfig) getTagKey() string {
+	tagKey := cfg.configBeforeFrozen.TagKey
+	if tagKey == "" {
+		return "json"
+	}
+	return tagKey
+}
+
+func (cfg *frozenConfig) RegisterExtension(extension Extension) {
+	cfg.extraExtensions = append(cfg.extraExtensions, extension)
+	copied := cfg.configBeforeFrozen
+	cfg.configBeforeFrozen = copied
+}
+
+type lossyFloat32Encoder struct {
+}
+
+func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteFloat32Lossy(*((*float32)(ptr)))
+}
+
+func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*float32)(ptr)) == 0
+}
+
+type lossyFloat64Encoder struct {
+}
+
+func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteFloat64Lossy(*((*float64)(ptr)))
+}
+
+func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*float64)(ptr)) == 0
+}
+
+// EnableLossyFloatMarshalling keeps 10**(-6) precision
+// for float variables for better performance.
+func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) {
+	// for better performance
+	extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{}
+	extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{}
+}
+
+type htmlEscapedStringEncoder struct {
+}
+
+func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	str := *((*string)(ptr))
+	stream.WriteStringWithHTMLEscaped(str)
+}
+
+func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*string)(ptr)) == ""
+}
+
+func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) {
+	encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{}
+}
+
+func (cfg *frozenConfig) cleanDecoders() {
+	typeDecoders = map[string]ValDecoder{}
+	fieldDecoders = map[string]ValDecoder{}
+	*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
+}
+
+func (cfg *frozenConfig) cleanEncoders() {
+	typeEncoders = map[string]ValEncoder{}
+	fieldEncoders = map[string]ValEncoder{}
+	*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
+}
+
+func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) {
+	stream := cfg.BorrowStream(nil)
+	defer cfg.ReturnStream(stream)
+	stream.WriteVal(v)
+	if stream.Error != nil {
+		return "", stream.Error
+	}
+	return string(stream.Buffer()), nil
+}
+
+func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) {
+	stream := cfg.BorrowStream(nil)
+	defer cfg.ReturnStream(stream)
+	stream.WriteVal(v)
+	if stream.Error != nil {
+		return nil, stream.Error
+	}
+	result := stream.Buffer()
+	copied := make([]byte, len(result))
+	copy(copied, result)
+	return copied, nil
+}
+
+func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
+	if prefix != "" {
+		panic("prefix is not supported")
+	}
+	for _, r := range indent {
+		if r != ' ' {
+			panic("indent can only be space")
+		}
+	}
+	newCfg := cfg.configBeforeFrozen
+	newCfg.IndentionStep = len(indent)
+	return newCfg.frozeWithCacheReuse(cfg.extraExtensions).Marshal(v)
+}
+
+func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error {
+	data := []byte(str)
+	iter := cfg.BorrowIterator(data)
+	defer cfg.ReturnIterator(iter)
+	iter.ReadVal(v)
+	c := iter.nextToken()
+	if c == 0 {
+		if iter.Error == io.EOF {
+			return nil
+		}
+		return iter.Error
+	}
+	iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
+	return iter.Error
+}
+
+func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any {
+	iter := cfg.BorrowIterator(data)
+	defer cfg.ReturnIterator(iter)
+	return locatePath(iter, path)
+}
+
+func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error {
+	iter := cfg.BorrowIterator(data)
+	defer cfg.ReturnIterator(iter)
+	iter.ReadVal(v)
+	c := iter.nextToken()
+	if c == 0 {
+		if iter.Error == io.EOF {
+			return nil
+		}
+		return iter.Error
+	}
+	iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
+	return iter.Error
+}
+
+func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder {
+	stream := NewStream(cfg, writer, 512)
+	return &Encoder{stream}
+}
+
+func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder {
+	iter := Parse(cfg, reader, 512)
+	return &Decoder{iter}
+}
+
+func (cfg *frozenConfig) Valid(data []byte) bool {
+	iter := cfg.BorrowIterator(data)
+	defer cfg.ReturnIterator(iter)
+	iter.Skip()
+	return iter.Error == nil
+}

+ 322 - 0
vendor/github.com/json-iterator/go/iter.go

@@ -0,0 +1,322 @@
+package jsoniter
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+)
+
+// ValueType the type for JSON element
+type ValueType int
+
+const (
+	// InvalidValue invalid JSON element
+	InvalidValue ValueType = iota
+	// StringValue JSON element "string"
+	StringValue
+	// NumberValue JSON element 100 or 0.10
+	NumberValue
+	// NilValue JSON element null
+	NilValue
+	// BoolValue JSON element true or false
+	BoolValue
+	// ArrayValue JSON element []
+	ArrayValue
+	// ObjectValue JSON element {}
+	ObjectValue
+)
+
+var hexDigits []byte
+var valueTypes []ValueType
+
+func init() {
+	hexDigits = make([]byte, 256)
+	for i := 0; i < len(hexDigits); i++ {
+		hexDigits[i] = 255
+	}
+	for i := '0'; i <= '9'; i++ {
+		hexDigits[i] = byte(i - '0')
+	}
+	for i := 'a'; i <= 'f'; i++ {
+		hexDigits[i] = byte((i - 'a') + 10)
+	}
+	for i := 'A'; i <= 'F'; i++ {
+		hexDigits[i] = byte((i - 'A') + 10)
+	}
+	valueTypes = make([]ValueType, 256)
+	for i := 0; i < len(valueTypes); i++ {
+		valueTypes[i] = InvalidValue
+	}
+	valueTypes['"'] = StringValue
+	valueTypes['-'] = NumberValue
+	valueTypes['0'] = NumberValue
+	valueTypes['1'] = NumberValue
+	valueTypes['2'] = NumberValue
+	valueTypes['3'] = NumberValue
+	valueTypes['4'] = NumberValue
+	valueTypes['5'] = NumberValue
+	valueTypes['6'] = NumberValue
+	valueTypes['7'] = NumberValue
+	valueTypes['8'] = NumberValue
+	valueTypes['9'] = NumberValue
+	valueTypes['t'] = BoolValue
+	valueTypes['f'] = BoolValue
+	valueTypes['n'] = NilValue
+	valueTypes['['] = ArrayValue
+	valueTypes['{'] = ObjectValue
+}
+
+// Iterator is a io.Reader like object, with JSON specific read functions.
+// Error is not returned as return value, but stored as Error member on this iterator instance.
+type Iterator struct {
+	cfg              *frozenConfig
+	reader           io.Reader
+	buf              []byte
+	head             int
+	tail             int
+	captureStartedAt int
+	captured         []byte
+	Error            error
+	Attachment       interface{} // open for customized decoder
+}
+
+// NewIterator creates an empty Iterator instance
+func NewIterator(cfg API) *Iterator {
+	return &Iterator{
+		cfg:    cfg.(*frozenConfig),
+		reader: nil,
+		buf:    nil,
+		head:   0,
+		tail:   0,
+	}
+}
+
+// Parse creates an Iterator instance from io.Reader
+func Parse(cfg API, reader io.Reader, bufSize int) *Iterator {
+	return &Iterator{
+		cfg:    cfg.(*frozenConfig),
+		reader: reader,
+		buf:    make([]byte, bufSize),
+		head:   0,
+		tail:   0,
+	}
+}
+
+// ParseBytes creates an Iterator instance from byte array
+func ParseBytes(cfg API, input []byte) *Iterator {
+	return &Iterator{
+		cfg:    cfg.(*frozenConfig),
+		reader: nil,
+		buf:    input,
+		head:   0,
+		tail:   len(input),
+	}
+}
+
+// ParseString creates an Iterator instance from string
+func ParseString(cfg API, input string) *Iterator {
+	return ParseBytes(cfg, []byte(input))
+}
+
+// Pool returns a pool can provide more iterator with same configuration
+func (iter *Iterator) Pool() IteratorPool {
+	return iter.cfg
+}
+
+// Reset reuse iterator instance by specifying another reader
+func (iter *Iterator) Reset(reader io.Reader) *Iterator {
+	iter.reader = reader
+	iter.head = 0
+	iter.tail = 0
+	return iter
+}
+
+// ResetBytes reuse iterator instance by specifying another byte array as input
+func (iter *Iterator) ResetBytes(input []byte) *Iterator {
+	iter.reader = nil
+	iter.buf = input
+	iter.head = 0
+	iter.tail = len(input)
+	return iter
+}
+
+// WhatIsNext gets ValueType of relatively next json element
+func (iter *Iterator) WhatIsNext() ValueType {
+	valueType := valueTypes[iter.nextToken()]
+	iter.unreadByte()
+	return valueType
+}
+
+func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool {
+	for i := iter.head; i < iter.tail; i++ {
+		c := iter.buf[i]
+		switch c {
+		case ' ', '\n', '\t', '\r':
+			continue
+		}
+		iter.head = i
+		return false
+	}
+	return true
+}
+
+func (iter *Iterator) isObjectEnd() bool {
+	c := iter.nextToken()
+	if c == ',' {
+		return false
+	}
+	if c == '}' {
+		return true
+	}
+	iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c}))
+	return true
+}
+
+func (iter *Iterator) nextToken() byte {
+	// a variation of skip whitespaces, returning the next non-whitespace token
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			c := iter.buf[i]
+			switch c {
+			case ' ', '\n', '\t', '\r':
+				continue
+			}
+			iter.head = i + 1
+			return c
+		}
+		if !iter.loadMore() {
+			return 0
+		}
+	}
+}
+
+// ReportError record a error in iterator instance with current position.
+func (iter *Iterator) ReportError(operation string, msg string) {
+	if iter.Error != nil {
+		if iter.Error != io.EOF {
+			return
+		}
+	}
+	peekStart := iter.head - 10
+	if peekStart < 0 {
+		peekStart = 0
+	}
+	peekEnd := iter.head + 10
+	if peekEnd > iter.tail {
+		peekEnd = iter.tail
+	}
+	parsing := string(iter.buf[peekStart:peekEnd])
+	contextStart := iter.head - 50
+	if contextStart < 0 {
+		contextStart = 0
+	}
+	contextEnd := iter.head + 50
+	if contextEnd > iter.tail {
+		contextEnd = iter.tail
+	}
+	context := string(iter.buf[contextStart:contextEnd])
+	iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
+		operation, msg, iter.head-peekStart, parsing, context)
+}
+
+// CurrentBuffer gets current buffer as string for debugging purpose
+func (iter *Iterator) CurrentBuffer() string {
+	peekStart := iter.head - 10
+	if peekStart < 0 {
+		peekStart = 0
+	}
+	return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head,
+		string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
+}
+
+func (iter *Iterator) readByte() (ret byte) {
+	if iter.head == iter.tail {
+		if iter.loadMore() {
+			ret = iter.buf[iter.head]
+			iter.head++
+			return ret
+		}
+		return 0
+	}
+	ret = iter.buf[iter.head]
+	iter.head++
+	return ret
+}
+
+func (iter *Iterator) loadMore() bool {
+	if iter.reader == nil {
+		if iter.Error == nil {
+			iter.head = iter.tail
+			iter.Error = io.EOF
+		}
+		return false
+	}
+	if iter.captured != nil {
+		iter.captured = append(iter.captured,
+			iter.buf[iter.captureStartedAt:iter.tail]...)
+		iter.captureStartedAt = 0
+	}
+	for {
+		n, err := iter.reader.Read(iter.buf)
+		if n == 0 {
+			if err != nil {
+				if iter.Error == nil {
+					iter.Error = err
+				}
+				return false
+			}
+		} else {
+			iter.head = 0
+			iter.tail = n
+			return true
+		}
+	}
+}
+
+func (iter *Iterator) unreadByte() {
+	if iter.Error != nil {
+		return
+	}
+	iter.head--
+	return
+}
+
+// Read read the next JSON element as generic interface{}.
+func (iter *Iterator) Read() interface{} {
+	valueType := iter.WhatIsNext()
+	switch valueType {
+	case StringValue:
+		return iter.ReadString()
+	case NumberValue:
+		if iter.cfg.configBeforeFrozen.UseNumber {
+			return json.Number(iter.readNumberAsString())
+		}
+		return iter.ReadFloat64()
+	case NilValue:
+		iter.skipFourBytes('n', 'u', 'l', 'l')
+		return nil
+	case BoolValue:
+		return iter.ReadBool()
+	case ArrayValue:
+		arr := []interface{}{}
+		iter.ReadArrayCB(func(iter *Iterator) bool {
+			var elem interface{}
+			iter.ReadVal(&elem)
+			arr = append(arr, elem)
+			return true
+		})
+		return arr
+	case ObjectValue:
+		obj := map[string]interface{}{}
+		iter.ReadMapCB(func(Iter *Iterator, field string) bool {
+			var elem interface{}
+			iter.ReadVal(&elem)
+			obj[field] = elem
+			return true
+		})
+		return obj
+	default:
+		iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))
+		return nil
+	}
+}

+ 58 - 0
vendor/github.com/json-iterator/go/iter_array.go

@@ -0,0 +1,58 @@
+package jsoniter
+
+// ReadArray read array element, tells if the array has more element to read.
+func (iter *Iterator) ReadArray() (ret bool) {
+	c := iter.nextToken()
+	switch c {
+	case 'n':
+		iter.skipThreeBytes('u', 'l', 'l')
+		return false // null
+	case '[':
+		c = iter.nextToken()
+		if c != ']' {
+			iter.unreadByte()
+			return true
+		}
+		return false
+	case ']':
+		return false
+	case ',':
+		return true
+	default:
+		iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c}))
+		return
+	}
+}
+
+// ReadArrayCB read array with callback
+func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) {
+	c := iter.nextToken()
+	if c == '[' {
+		c = iter.nextToken()
+		if c != ']' {
+			iter.unreadByte()
+			if !callback(iter) {
+				return false
+			}
+			c = iter.nextToken()
+			for c == ',' {
+				if !callback(iter) {
+					return false
+				}
+				c = iter.nextToken()
+			}
+			if c != ']' {
+				iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c}))
+				return false
+			}
+			return true
+		}
+		return true
+	}
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return true // null
+	}
+	iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c}))
+	return false
+}

+ 347 - 0
vendor/github.com/json-iterator/go/iter_float.go

@@ -0,0 +1,347 @@
+package jsoniter
+
+import (
+	"encoding/json"
+	"io"
+	"math/big"
+	"strconv"
+	"strings"
+	"unsafe"
+)
+
+var floatDigits []int8
+
+const invalidCharForNumber = int8(-1)
+const endOfNumber = int8(-2)
+const dotInNumber = int8(-3)
+
+func init() {
+	floatDigits = make([]int8, 256)
+	for i := 0; i < len(floatDigits); i++ {
+		floatDigits[i] = invalidCharForNumber
+	}
+	for i := int8('0'); i <= int8('9'); i++ {
+		floatDigits[i] = i - int8('0')
+	}
+	floatDigits[','] = endOfNumber
+	floatDigits[']'] = endOfNumber
+	floatDigits['}'] = endOfNumber
+	floatDigits[' '] = endOfNumber
+	floatDigits['\t'] = endOfNumber
+	floatDigits['\n'] = endOfNumber
+	floatDigits['.'] = dotInNumber
+}
+
+// ReadBigFloat read big.Float
+func (iter *Iterator) ReadBigFloat() (ret *big.Float) {
+	str := iter.readNumberAsString()
+	if iter.Error != nil && iter.Error != io.EOF {
+		return nil
+	}
+	prec := 64
+	if len(str) > prec {
+		prec = len(str)
+	}
+	val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero)
+	if err != nil {
+		iter.Error = err
+		return nil
+	}
+	return val
+}
+
+// ReadBigInt read big.Int
+func (iter *Iterator) ReadBigInt() (ret *big.Int) {
+	str := iter.readNumberAsString()
+	if iter.Error != nil && iter.Error != io.EOF {
+		return nil
+	}
+	ret = big.NewInt(0)
+	var success bool
+	ret, success = ret.SetString(str, 10)
+	if !success {
+		iter.ReportError("ReadBigInt", "invalid big int")
+		return nil
+	}
+	return ret
+}
+
+//ReadFloat32 read float32
+func (iter *Iterator) ReadFloat32() (ret float32) {
+	c := iter.nextToken()
+	if c == '-' {
+		return -iter.readPositiveFloat32()
+	}
+	iter.unreadByte()
+	return iter.readPositiveFloat32()
+}
+
+func (iter *Iterator) readPositiveFloat32() (ret float32) {
+	value := uint64(0)
+	c := byte(' ')
+	i := iter.head
+	// first char
+	if i == iter.tail {
+		return iter.readFloat32SlowPath()
+	}
+	c = iter.buf[i]
+	i++
+	ind := floatDigits[c]
+	switch ind {
+	case invalidCharForNumber:
+		return iter.readFloat32SlowPath()
+	case endOfNumber:
+		iter.ReportError("readFloat32", "empty number")
+		return
+	case dotInNumber:
+		iter.ReportError("readFloat32", "leading dot is invalid")
+		return
+	case 0:
+		if i == iter.tail {
+			return iter.readFloat32SlowPath()
+		}
+		c = iter.buf[i]
+		switch c {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+			iter.ReportError("readFloat32", "leading zero is invalid")
+			return
+		}
+	}
+	value = uint64(ind)
+	// chars before dot
+non_decimal_loop:
+	for ; i < iter.tail; i++ {
+		c = iter.buf[i]
+		ind := floatDigits[c]
+		switch ind {
+		case invalidCharForNumber:
+			return iter.readFloat32SlowPath()
+		case endOfNumber:
+			iter.head = i
+			return float32(value)
+		case dotInNumber:
+			break non_decimal_loop
+		}
+		if value > uint64SafeToMultiple10 {
+			return iter.readFloat32SlowPath()
+		}
+		value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
+	}
+	// chars after dot
+	if c == '.' {
+		i++
+		decimalPlaces := 0
+		if i == iter.tail {
+			return iter.readFloat32SlowPath()
+		}
+		for ; i < iter.tail; i++ {
+			c = iter.buf[i]
+			ind := floatDigits[c]
+			switch ind {
+			case endOfNumber:
+				if decimalPlaces > 0 && decimalPlaces < len(pow10) {
+					iter.head = i
+					return float32(float64(value) / float64(pow10[decimalPlaces]))
+				}
+				// too many decimal places
+				return iter.readFloat32SlowPath()
+			case invalidCharForNumber:
+				fallthrough
+			case dotInNumber:
+				return iter.readFloat32SlowPath()
+			}
+			decimalPlaces++
+			if value > uint64SafeToMultiple10 {
+				return iter.readFloat32SlowPath()
+			}
+			value = (value << 3) + (value << 1) + uint64(ind)
+		}
+	}
+	return iter.readFloat32SlowPath()
+}
+
+func (iter *Iterator) readNumberAsString() (ret string) {
+	strBuf := [16]byte{}
+	str := strBuf[0:0]
+load_loop:
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			c := iter.buf[i]
+			switch c {
+			case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+				str = append(str, c)
+				continue
+			default:
+				iter.head = i
+				break load_loop
+			}
+		}
+		if !iter.loadMore() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		return
+	}
+	if len(str) == 0 {
+		iter.ReportError("readNumberAsString", "invalid number")
+	}
+	return *(*string)(unsafe.Pointer(&str))
+}
+
+func (iter *Iterator) readFloat32SlowPath() (ret float32) {
+	str := iter.readNumberAsString()
+	if iter.Error != nil && iter.Error != io.EOF {
+		return
+	}
+	errMsg := validateFloat(str)
+	if errMsg != "" {
+		iter.ReportError("readFloat32SlowPath", errMsg)
+		return
+	}
+	val, err := strconv.ParseFloat(str, 32)
+	if err != nil {
+		iter.Error = err
+		return
+	}
+	return float32(val)
+}
+
+// ReadFloat64 read float64
+func (iter *Iterator) ReadFloat64() (ret float64) {
+	c := iter.nextToken()
+	if c == '-' {
+		return -iter.readPositiveFloat64()
+	}
+	iter.unreadByte()
+	return iter.readPositiveFloat64()
+}
+
+func (iter *Iterator) readPositiveFloat64() (ret float64) {
+	value := uint64(0)
+	c := byte(' ')
+	i := iter.head
+	// first char
+	if i == iter.tail {
+		return iter.readFloat64SlowPath()
+	}
+	c = iter.buf[i]
+	i++
+	ind := floatDigits[c]
+	switch ind {
+	case invalidCharForNumber:
+		return iter.readFloat64SlowPath()
+	case endOfNumber:
+		iter.ReportError("readFloat64", "empty number")
+		return
+	case dotInNumber:
+		iter.ReportError("readFloat64", "leading dot is invalid")
+		return
+	case 0:
+		if i == iter.tail {
+			return iter.readFloat64SlowPath()
+		}
+		c = iter.buf[i]
+		switch c {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+			iter.ReportError("readFloat64", "leading zero is invalid")
+			return
+		}
+	}
+	value = uint64(ind)
+	// chars before dot
+non_decimal_loop:
+	for ; i < iter.tail; i++ {
+		c = iter.buf[i]
+		ind := floatDigits[c]
+		switch ind {
+		case invalidCharForNumber:
+			return iter.readFloat64SlowPath()
+		case endOfNumber:
+			iter.head = i
+			return float64(value)
+		case dotInNumber:
+			break non_decimal_loop
+		}
+		if value > uint64SafeToMultiple10 {
+			return iter.readFloat64SlowPath()
+		}
+		value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
+	}
+	// chars after dot
+	if c == '.' {
+		i++
+		decimalPlaces := 0
+		if i == iter.tail {
+			return iter.readFloat64SlowPath()
+		}
+		for ; i < iter.tail; i++ {
+			c = iter.buf[i]
+			ind := floatDigits[c]
+			switch ind {
+			case endOfNumber:
+				if decimalPlaces > 0 && decimalPlaces < len(pow10) {
+					iter.head = i
+					return float64(value) / float64(pow10[decimalPlaces])
+				}
+				// too many decimal places
+				return iter.readFloat64SlowPath()
+			case invalidCharForNumber:
+				fallthrough
+			case dotInNumber:
+				return iter.readFloat64SlowPath()
+			}
+			decimalPlaces++
+			if value > uint64SafeToMultiple10 {
+				return iter.readFloat64SlowPath()
+			}
+			value = (value << 3) + (value << 1) + uint64(ind)
+		}
+	}
+	return iter.readFloat64SlowPath()
+}
+
+func (iter *Iterator) readFloat64SlowPath() (ret float64) {
+	str := iter.readNumberAsString()
+	if iter.Error != nil && iter.Error != io.EOF {
+		return
+	}
+	errMsg := validateFloat(str)
+	if errMsg != "" {
+		iter.ReportError("readFloat64SlowPath", errMsg)
+		return
+	}
+	val, err := strconv.ParseFloat(str, 64)
+	if err != nil {
+		iter.Error = err
+		return
+	}
+	return val
+}
+
+func validateFloat(str string) string {
+	// strconv.ParseFloat is not validating `1.` or `1.e1`
+	if len(str) == 0 {
+		return "empty number"
+	}
+	if str[0] == '-' {
+		return "-- is not valid"
+	}
+	dotPos := strings.IndexByte(str, '.')
+	if dotPos != -1 {
+		if dotPos == len(str)-1 {
+			return "dot can not be last character"
+		}
+		switch str[dotPos+1] {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+		default:
+			return "missing digit after dot"
+		}
+	}
+	return ""
+}
+
+// ReadNumber read json.Number
+func (iter *Iterator) ReadNumber() (ret json.Number) {
+	return json.Number(iter.readNumberAsString())
+}

+ 345 - 0
vendor/github.com/json-iterator/go/iter_int.go

@@ -0,0 +1,345 @@
+package jsoniter
+
+import (
+	"math"
+	"strconv"
+)
+
+var intDigits []int8
+
+const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1
+const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1
+
+func init() {
+	intDigits = make([]int8, 256)
+	for i := 0; i < len(intDigits); i++ {
+		intDigits[i] = invalidCharForNumber
+	}
+	for i := int8('0'); i <= int8('9'); i++ {
+		intDigits[i] = i - int8('0')
+	}
+}
+
+// ReadUint read uint
+func (iter *Iterator) ReadUint() uint {
+	if strconv.IntSize == 32 {
+		return uint(iter.ReadUint32())
+	}
+	return uint(iter.ReadUint64())
+}
+
+// ReadInt read int
+func (iter *Iterator) ReadInt() int {
+	if strconv.IntSize == 32 {
+		return int(iter.ReadInt32())
+	}
+	return int(iter.ReadInt64())
+}
+
+// ReadInt8 read int8
+func (iter *Iterator) ReadInt8() (ret int8) {
+	c := iter.nextToken()
+	if c == '-' {
+		val := iter.readUint32(iter.readByte())
+		if val > math.MaxInt8+1 {
+			iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
+			return
+		}
+		return -int8(val)
+	}
+	val := iter.readUint32(c)
+	if val > math.MaxInt8 {
+		iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
+		return
+	}
+	return int8(val)
+}
+
+// ReadUint8 read uint8
+func (iter *Iterator) ReadUint8() (ret uint8) {
+	val := iter.readUint32(iter.nextToken())
+	if val > math.MaxUint8 {
+		iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10))
+		return
+	}
+	return uint8(val)
+}
+
+// ReadInt16 read int16
+func (iter *Iterator) ReadInt16() (ret int16) {
+	c := iter.nextToken()
+	if c == '-' {
+		val := iter.readUint32(iter.readByte())
+		if val > math.MaxInt16+1 {
+			iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
+			return
+		}
+		return -int16(val)
+	}
+	val := iter.readUint32(c)
+	if val > math.MaxInt16 {
+		iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
+		return
+	}
+	return int16(val)
+}
+
+// ReadUint16 read uint16
+func (iter *Iterator) ReadUint16() (ret uint16) {
+	val := iter.readUint32(iter.nextToken())
+	if val > math.MaxUint16 {
+		iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10))
+		return
+	}
+	return uint16(val)
+}
+
+// ReadInt32 read int32
+func (iter *Iterator) ReadInt32() (ret int32) {
+	c := iter.nextToken()
+	if c == '-' {
+		val := iter.readUint32(iter.readByte())
+		if val > math.MaxInt32+1 {
+			iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
+			return
+		}
+		return -int32(val)
+	}
+	val := iter.readUint32(c)
+	if val > math.MaxInt32 {
+		iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
+		return
+	}
+	return int32(val)
+}
+
+// ReadUint32 read uint32
+func (iter *Iterator) ReadUint32() (ret uint32) {
+	return iter.readUint32(iter.nextToken())
+}
+
+func (iter *Iterator) readUint32(c byte) (ret uint32) {
+	ind := intDigits[c]
+	if ind == 0 {
+		iter.assertInteger()
+		return 0 // single zero
+	}
+	if ind == invalidCharForNumber {
+		iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)}))
+		return
+	}
+	value := uint32(ind)
+	if iter.tail-iter.head > 10 {
+		i := iter.head
+		ind2 := intDigits[iter.buf[i]]
+		if ind2 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value
+		}
+		i++
+		ind3 := intDigits[iter.buf[i]]
+		if ind3 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*10 + uint32(ind2)
+		}
+		//iter.head = i + 1
+		//value = value * 100 + uint32(ind2) * 10 + uint32(ind3)
+		i++
+		ind4 := intDigits[iter.buf[i]]
+		if ind4 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*100 + uint32(ind2)*10 + uint32(ind3)
+		}
+		i++
+		ind5 := intDigits[iter.buf[i]]
+		if ind5 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4)
+		}
+		i++
+		ind6 := intDigits[iter.buf[i]]
+		if ind6 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5)
+		}
+		i++
+		ind7 := intDigits[iter.buf[i]]
+		if ind7 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6)
+		}
+		i++
+		ind8 := intDigits[iter.buf[i]]
+		if ind8 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7)
+		}
+		i++
+		ind9 := intDigits[iter.buf[i]]
+		value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8)
+		iter.head = i
+		if ind9 == invalidCharForNumber {
+			iter.assertInteger()
+			return value
+		}
+	}
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			ind = intDigits[iter.buf[i]]
+			if ind == invalidCharForNumber {
+				iter.head = i
+				iter.assertInteger()
+				return value
+			}
+			if value > uint32SafeToMultiply10 {
+				value2 := (value << 3) + (value << 1) + uint32(ind)
+				if value2 < value {
+					iter.ReportError("readUint32", "overflow")
+					return
+				}
+				value = value2
+				continue
+			}
+			value = (value << 3) + (value << 1) + uint32(ind)
+		}
+		if !iter.loadMore() {
+			iter.assertInteger()
+			return value
+		}
+	}
+}
+
+// ReadInt64 read int64
+func (iter *Iterator) ReadInt64() (ret int64) {
+	c := iter.nextToken()
+	if c == '-' {
+		val := iter.readUint64(iter.readByte())
+		if val > math.MaxInt64+1 {
+			iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
+			return
+		}
+		return -int64(val)
+	}
+	val := iter.readUint64(c)
+	if val > math.MaxInt64 {
+		iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
+		return
+	}
+	return int64(val)
+}
+
+// ReadUint64 read uint64
+func (iter *Iterator) ReadUint64() uint64 {
+	return iter.readUint64(iter.nextToken())
+}
+
+func (iter *Iterator) readUint64(c byte) (ret uint64) {
+	ind := intDigits[c]
+	if ind == 0 {
+		iter.assertInteger()
+		return 0 // single zero
+	}
+	if ind == invalidCharForNumber {
+		iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)}))
+		return
+	}
+	value := uint64(ind)
+	if iter.tail-iter.head > 10 {
+		i := iter.head
+		ind2 := intDigits[iter.buf[i]]
+		if ind2 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value
+		}
+		i++
+		ind3 := intDigits[iter.buf[i]]
+		if ind3 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*10 + uint64(ind2)
+		}
+		//iter.head = i + 1
+		//value = value * 100 + uint32(ind2) * 10 + uint32(ind3)
+		i++
+		ind4 := intDigits[iter.buf[i]]
+		if ind4 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*100 + uint64(ind2)*10 + uint64(ind3)
+		}
+		i++
+		ind5 := intDigits[iter.buf[i]]
+		if ind5 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4)
+		}
+		i++
+		ind6 := intDigits[iter.buf[i]]
+		if ind6 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5)
+		}
+		i++
+		ind7 := intDigits[iter.buf[i]]
+		if ind7 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6)
+		}
+		i++
+		ind8 := intDigits[iter.buf[i]]
+		if ind8 == invalidCharForNumber {
+			iter.head = i
+			iter.assertInteger()
+			return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7)
+		}
+		i++
+		ind9 := intDigits[iter.buf[i]]
+		value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8)
+		iter.head = i
+		if ind9 == invalidCharForNumber {
+			iter.assertInteger()
+			return value
+		}
+	}
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			ind = intDigits[iter.buf[i]]
+			if ind == invalidCharForNumber {
+				iter.head = i
+				iter.assertInteger()
+				return value
+			}
+			if value > uint64SafeToMultiple10 {
+				value2 := (value << 3) + (value << 1) + uint64(ind)
+				if value2 < value {
+					iter.ReportError("readUint64", "overflow")
+					return
+				}
+				value = value2
+				continue
+			}
+			value = (value << 3) + (value << 1) + uint64(ind)
+		}
+		if !iter.loadMore() {
+			iter.assertInteger()
+			return value
+		}
+	}
+}
+
+func (iter *Iterator) assertInteger() {
+	if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' {
+		iter.ReportError("assertInteger", "can not decode float as int")
+	}
+}

+ 251 - 0
vendor/github.com/json-iterator/go/iter_object.go

@@ -0,0 +1,251 @@
+package jsoniter
+
+import (
+	"fmt"
+	"strings"
+)
+
+// ReadObject read one field from object.
+// If object ended, returns empty string.
+// Otherwise, returns the field name.
+func (iter *Iterator) ReadObject() (ret string) {
+	c := iter.nextToken()
+	switch c {
+	case 'n':
+		iter.skipThreeBytes('u', 'l', 'l')
+		return "" // null
+	case '{':
+		c = iter.nextToken()
+		if c == '"' {
+			iter.unreadByte()
+			field := iter.ReadString()
+			c = iter.nextToken()
+			if c != ':' {
+				iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
+			}
+			return field
+		}
+		if c == '}' {
+			return "" // end of object
+		}
+		iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c}))
+		return
+	case ',':
+		field := iter.ReadString()
+		c = iter.nextToken()
+		if c != ':' {
+			iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
+		}
+		return field
+	case '}':
+		return "" // end of object
+	default:
+		iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c})))
+		return
+	}
+}
+
+// CaseInsensitive
+func (iter *Iterator) readFieldHash() int64 {
+	hash := int64(0x811c9dc5)
+	c := iter.nextToken()
+	if c != '"' {
+		iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c}))
+		return 0
+	}
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			// require ascii string and no escape
+			b := iter.buf[i]
+			if b == '\\' {
+				iter.head = i
+				for _, b := range iter.readStringSlowPath() {
+					if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
+						b += 'a' - 'A'
+					}
+					hash ^= int64(b)
+					hash *= 0x1000193
+				}
+				c = iter.nextToken()
+				if c != ':' {
+					iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
+					return 0
+				}
+				return hash
+			}
+			if b == '"' {
+				iter.head = i + 1
+				c = iter.nextToken()
+				if c != ':' {
+					iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
+					return 0
+				}
+				return hash
+			}
+			if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
+				b += 'a' - 'A'
+			}
+			hash ^= int64(b)
+			hash *= 0x1000193
+		}
+		if !iter.loadMore() {
+			iter.ReportError("readFieldHash", `incomplete field name`)
+			return 0
+		}
+	}
+}
+
+func calcHash(str string, caseSensitive bool) int64 {
+	if !caseSensitive {
+		str = strings.ToLower(str)
+	}
+	hash := int64(0x811c9dc5)
+	for _, b := range []byte(str) {
+		hash ^= int64(b)
+		hash *= 0x1000193
+	}
+	return int64(hash)
+}
+
+// ReadObjectCB read object with callback, the key is ascii only and field name not copied
+func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
+	c := iter.nextToken()
+	var field string
+	if c == '{' {
+		c = iter.nextToken()
+		if c == '"' {
+			iter.unreadByte()
+			field = iter.ReadString()
+			c = iter.nextToken()
+			if c != ':' {
+				iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
+			}
+			if !callback(iter, field) {
+				return false
+			}
+			c = iter.nextToken()
+			for c == ',' {
+				field = iter.ReadString()
+				c = iter.nextToken()
+				if c != ':' {
+					iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
+				}
+				if !callback(iter, field) {
+					return false
+				}
+				c = iter.nextToken()
+			}
+			if c != '}' {
+				iter.ReportError("ReadObjectCB", `object not ended with }`)
+				return false
+			}
+			return true
+		}
+		if c == '}' {
+			return true
+		}
+		iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c}))
+		return false
+	}
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return true // null
+	}
+	iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c}))
+	return false
+}
+
+// ReadMapCB read map with callback, the key can be any string
+func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
+	c := iter.nextToken()
+	if c == '{' {
+		c = iter.nextToken()
+		if c == '"' {
+			iter.unreadByte()
+			field := iter.ReadString()
+			if iter.nextToken() != ':' {
+				iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
+				return false
+			}
+			if !callback(iter, field) {
+				return false
+			}
+			c = iter.nextToken()
+			for c == ',' {
+				field = iter.ReadString()
+				if iter.nextToken() != ':' {
+					iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
+					return false
+				}
+				if !callback(iter, field) {
+					return false
+				}
+				c = iter.nextToken()
+			}
+			if c != '}' {
+				iter.ReportError("ReadMapCB", `object not ended with }`)
+				return false
+			}
+			return true
+		}
+		if c == '}' {
+			return true
+		}
+		iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
+		return false
+	}
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return true // null
+	}
+	iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
+	return false
+}
+
+func (iter *Iterator) readObjectStart() bool {
+	c := iter.nextToken()
+	if c == '{' {
+		c = iter.nextToken()
+		if c == '}' {
+			return false
+		}
+		iter.unreadByte()
+		return true
+	} else if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return false
+	}
+	iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c}))
+	return false
+}
+
+func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) {
+	str := iter.ReadStringAsSlice()
+	if iter.skipWhitespacesWithoutLoadMore() {
+		if ret == nil {
+			ret = make([]byte, len(str))
+			copy(ret, str)
+		}
+		if !iter.loadMore() {
+			return
+		}
+	}
+	if iter.buf[iter.head] != ':' {
+		iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]}))
+		return
+	}
+	iter.head++
+	if iter.skipWhitespacesWithoutLoadMore() {
+		if ret == nil {
+			ret = make([]byte, len(str))
+			copy(ret, str)
+		}
+		if !iter.loadMore() {
+			return
+		}
+	}
+	if ret == nil {
+		return str
+	}
+	return ret
+}

+ 129 - 0
vendor/github.com/json-iterator/go/iter_skip.go

@@ -0,0 +1,129 @@
+package jsoniter
+
+import "fmt"
+
+// ReadNil reads a json object as nil and
+// returns whether it's a nil or not
+func (iter *Iterator) ReadNil() (ret bool) {
+	c := iter.nextToken()
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l') // null
+		return true
+	}
+	iter.unreadByte()
+	return false
+}
+
+// ReadBool reads a json object as BoolValue
+func (iter *Iterator) ReadBool() (ret bool) {
+	c := iter.nextToken()
+	if c == 't' {
+		iter.skipThreeBytes('r', 'u', 'e')
+		return true
+	}
+	if c == 'f' {
+		iter.skipFourBytes('a', 'l', 's', 'e')
+		return false
+	}
+	iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c}))
+	return
+}
+
+// SkipAndReturnBytes skip next JSON element, and return its content as []byte.
+// The []byte can be kept, it is a copy of data.
+func (iter *Iterator) SkipAndReturnBytes() []byte {
+	iter.startCapture(iter.head)
+	iter.Skip()
+	return iter.stopCapture()
+}
+
+type captureBuffer struct {
+	startedAt int
+	captured  []byte
+}
+
+func (iter *Iterator) startCapture(captureStartedAt int) {
+	if iter.captured != nil {
+		panic("already in capture mode")
+	}
+	iter.captureStartedAt = captureStartedAt
+	iter.captured = make([]byte, 0, 32)
+}
+
+func (iter *Iterator) stopCapture() []byte {
+	if iter.captured == nil {
+		panic("not in capture mode")
+	}
+	captured := iter.captured
+	remaining := iter.buf[iter.captureStartedAt:iter.head]
+	iter.captureStartedAt = -1
+	iter.captured = nil
+	if len(captured) == 0 {
+		copied := make([]byte, len(remaining))
+		copy(copied, remaining)
+		return copied
+	}
+	captured = append(captured, remaining...)
+	return captured
+}
+
+// Skip skips a json object and positions to relatively the next json object
+func (iter *Iterator) Skip() {
+	c := iter.nextToken()
+	switch c {
+	case '"':
+		iter.skipString()
+	case 'n':
+		iter.skipThreeBytes('u', 'l', 'l') // null
+	case 't':
+		iter.skipThreeBytes('r', 'u', 'e') // true
+	case 'f':
+		iter.skipFourBytes('a', 'l', 's', 'e') // false
+	case '0':
+		iter.unreadByte()
+		iter.ReadFloat32()
+	case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+		iter.skipNumber()
+	case '[':
+		iter.skipArray()
+	case '{':
+		iter.skipObject()
+	default:
+		iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
+		return
+	}
+}
+
+func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) {
+	if iter.readByte() != b1 {
+		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
+		return
+	}
+	if iter.readByte() != b2 {
+		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
+		return
+	}
+	if iter.readByte() != b3 {
+		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
+		return
+	}
+	if iter.readByte() != b4 {
+		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
+		return
+	}
+}
+
+func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) {
+	if iter.readByte() != b1 {
+		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
+		return
+	}
+	if iter.readByte() != b2 {
+		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
+		return
+	}
+	if iter.readByte() != b3 {
+		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
+		return
+	}
+}

+ 144 - 0
vendor/github.com/json-iterator/go/iter_skip_sloppy.go

@@ -0,0 +1,144 @@
+//+build jsoniter_sloppy
+
+package jsoniter
+
+// sloppy but faster implementation, do not validate the input json
+
+func (iter *Iterator) skipNumber() {
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			c := iter.buf[i]
+			switch c {
+			case ' ', '\n', '\r', '\t', ',', '}', ']':
+				iter.head = i
+				return
+			}
+		}
+		if !iter.loadMore() {
+			return
+		}
+	}
+}
+
+func (iter *Iterator) skipArray() {
+	level := 1
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			switch iter.buf[i] {
+			case '"': // If inside string, skip it
+				iter.head = i + 1
+				iter.skipString()
+				i = iter.head - 1 // it will be i++ soon
+			case '[': // If open symbol, increase level
+				level++
+			case ']': // If close symbol, increase level
+				level--
+
+				// If we have returned to the original level, we're done
+				if level == 0 {
+					iter.head = i + 1
+					return
+				}
+			}
+		}
+		if !iter.loadMore() {
+			iter.ReportError("skipObject", "incomplete array")
+			return
+		}
+	}
+}
+
+func (iter *Iterator) skipObject() {
+	level := 1
+	for {
+		for i := iter.head; i < iter.tail; i++ {
+			switch iter.buf[i] {
+			case '"': // If inside string, skip it
+				iter.head = i + 1
+				iter.skipString()
+				i = iter.head - 1 // it will be i++ soon
+			case '{': // If open symbol, increase level
+				level++
+			case '}': // If close symbol, increase level
+				level--
+
+				// If we have returned to the original level, we're done
+				if level == 0 {
+					iter.head = i + 1
+					return
+				}
+			}
+		}
+		if !iter.loadMore() {
+			iter.ReportError("skipObject", "incomplete object")
+			return
+		}
+	}
+}
+
+func (iter *Iterator) skipString() {
+	for {
+		end, escaped := iter.findStringEnd()
+		if end == -1 {
+			if !iter.loadMore() {
+				iter.ReportError("skipString", "incomplete string")
+				return
+			}
+			if escaped {
+				iter.head = 1 // skip the first char as last char read is \
+			}
+		} else {
+			iter.head = end
+			return
+		}
+	}
+}
+
+// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go
+// Tries to find the end of string
+// Support if string contains escaped quote symbols.
+func (iter *Iterator) findStringEnd() (int, bool) {
+	escaped := false
+	for i := iter.head; i < iter.tail; i++ {
+		c := iter.buf[i]
+		if c == '"' {
+			if !escaped {
+				return i + 1, false
+			}
+			j := i - 1
+			for {
+				if j < iter.head || iter.buf[j] != '\\' {
+					// even number of backslashes
+					// either end of buffer, or " found
+					return i + 1, true
+				}
+				j--
+				if j < iter.head || iter.buf[j] != '\\' {
+					// odd number of backslashes
+					// it is \" or \\\"
+					break
+				}
+				j--
+			}
+		} else if c == '\\' {
+			escaped = true
+		}
+	}
+	j := iter.tail - 1
+	for {
+		if j < iter.head || iter.buf[j] != '\\' {
+			// even number of backslashes
+			// either end of buffer, or " found
+			return -1, false // do not end with \
+		}
+		j--
+		if j < iter.head || iter.buf[j] != '\\' {
+			// odd number of backslashes
+			// it is \" or \\\"
+			break
+		}
+		j--
+
+	}
+	return -1, true // end with \
+}

+ 89 - 0
vendor/github.com/json-iterator/go/iter_skip_strict.go

@@ -0,0 +1,89 @@
+//+build !jsoniter_sloppy
+
+package jsoniter
+
+import "fmt"
+
+func (iter *Iterator) skipNumber() {
+	if !iter.trySkipNumber() {
+		iter.unreadByte()
+		iter.ReadFloat32()
+	}
+}
+
+func (iter *Iterator) trySkipNumber() bool {
+	dotFound := false
+	for i := iter.head; i < iter.tail; i++ {
+		c := iter.buf[i]
+		switch c {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+		case '.':
+			if dotFound {
+				iter.ReportError("validateNumber", `more than one dot found in number`)
+				return true // already failed
+			}
+			if i+1 == iter.tail {
+				return false
+			}
+			c = iter.buf[i+1]
+			switch c {
+			case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+			default:
+				iter.ReportError("validateNumber", `missing digit after dot`)
+				return true // already failed
+			}
+			dotFound = true
+		default:
+			switch c {
+			case ',', ']', '}', ' ', '\t', '\n', '\r':
+				if iter.head == i {
+					return false // if - without following digits
+				}
+				iter.head = i
+				return true // must be valid
+			}
+			return false // may be invalid
+		}
+	}
+	return false
+}
+
+func (iter *Iterator) skipString() {
+	if !iter.trySkipString() {
+		iter.unreadByte()
+		iter.ReadString()
+	}
+}
+
+func (iter *Iterator) trySkipString() bool {
+	for i := iter.head; i < iter.tail; i++ {
+		c := iter.buf[i]
+		if c == '"' {
+			iter.head = i + 1
+			return true // valid
+		} else if c == '\\' {
+			return false
+		} else if c < ' ' {
+			iter.ReportError("trySkipString",
+				fmt.Sprintf(`invalid control character found: %d`, c))
+			return true // already failed
+		}
+	}
+	return false
+}
+
+func (iter *Iterator) skipObject() {
+	iter.unreadByte()
+	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
+		iter.Skip()
+		return true
+	})
+}
+
+func (iter *Iterator) skipArray() {
+	iter.unreadByte()
+	iter.ReadArrayCB(func(iter *Iterator) bool {
+		iter.Skip()
+		return true
+	})
+}

+ 215 - 0
vendor/github.com/json-iterator/go/iter_str.go

@@ -0,0 +1,215 @@
+package jsoniter
+
+import (
+	"fmt"
+	"unicode/utf16"
+)
+
+// ReadString read string from iterator
+func (iter *Iterator) ReadString() (ret string) {
+	c := iter.nextToken()
+	if c == '"' {
+		for i := iter.head; i < iter.tail; i++ {
+			c := iter.buf[i]
+			if c == '"' {
+				ret = string(iter.buf[iter.head:i])
+				iter.head = i + 1
+				return ret
+			} else if c == '\\' {
+				break
+			} else if c < ' ' {
+				iter.ReportError("ReadString",
+					fmt.Sprintf(`invalid control character found: %d`, c))
+				return
+			}
+		}
+		return iter.readStringSlowPath()
+	} else if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return ""
+	}
+	iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c}))
+	return
+}
+
+func (iter *Iterator) readStringSlowPath() (ret string) {
+	var str []byte
+	var c byte
+	for iter.Error == nil {
+		c = iter.readByte()
+		if c == '"' {
+			return string(str)
+		}
+		if c == '\\' {
+			c = iter.readByte()
+			str = iter.readEscapedChar(c, str)
+		} else {
+			str = append(str, c)
+		}
+	}
+	iter.ReportError("readStringSlowPath", "unexpected end of input")
+	return
+}
+
+func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte {
+	switch c {
+	case 'u':
+		r := iter.readU4()
+		if utf16.IsSurrogate(r) {
+			c = iter.readByte()
+			if iter.Error != nil {
+				return nil
+			}
+			if c != '\\' {
+				iter.unreadByte()
+				str = appendRune(str, r)
+				return str
+			}
+			c = iter.readByte()
+			if iter.Error != nil {
+				return nil
+			}
+			if c != 'u' {
+				str = appendRune(str, r)
+				return iter.readEscapedChar(c, str)
+			}
+			r2 := iter.readU4()
+			if iter.Error != nil {
+				return nil
+			}
+			combined := utf16.DecodeRune(r, r2)
+			if combined == '\uFFFD' {
+				str = appendRune(str, r)
+				str = appendRune(str, r2)
+			} else {
+				str = appendRune(str, combined)
+			}
+		} else {
+			str = appendRune(str, r)
+		}
+	case '"':
+		str = append(str, '"')
+	case '\\':
+		str = append(str, '\\')
+	case '/':
+		str = append(str, '/')
+	case 'b':
+		str = append(str, '\b')
+	case 'f':
+		str = append(str, '\f')
+	case 'n':
+		str = append(str, '\n')
+	case 'r':
+		str = append(str, '\r')
+	case 't':
+		str = append(str, '\t')
+	default:
+		iter.ReportError("readEscapedChar",
+			`invalid escape char after \`)
+		return nil
+	}
+	return str
+}
+
+// ReadStringAsSlice read string from iterator without copying into string form.
+// The []byte can not be kept, as it will change after next iterator call.
+func (iter *Iterator) ReadStringAsSlice() (ret []byte) {
+	c := iter.nextToken()
+	if c == '"' {
+		for i := iter.head; i < iter.tail; i++ {
+			// require ascii string and no escape
+			// for: field name, base64, number
+			if iter.buf[i] == '"' {
+				// fast path: reuse the underlying buffer
+				ret = iter.buf[iter.head:i]
+				iter.head = i + 1
+				return ret
+			}
+		}
+		readLen := iter.tail - iter.head
+		copied := make([]byte, readLen, readLen*2)
+		copy(copied, iter.buf[iter.head:iter.tail])
+		iter.head = iter.tail
+		for iter.Error == nil {
+			c := iter.readByte()
+			if c == '"' {
+				return copied
+			}
+			copied = append(copied, c)
+		}
+		return copied
+	}
+	iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c}))
+	return
+}
+
+func (iter *Iterator) readU4() (ret rune) {
+	for i := 0; i < 4; i++ {
+		c := iter.readByte()
+		if iter.Error != nil {
+			return
+		}
+		if c >= '0' && c <= '9' {
+			ret = ret*16 + rune(c-'0')
+		} else if c >= 'a' && c <= 'f' {
+			ret = ret*16 + rune(c-'a'+10)
+		} else if c >= 'A' && c <= 'F' {
+			ret = ret*16 + rune(c-'A'+10)
+		} else {
+			iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c}))
+			return
+		}
+	}
+	return ret
+}
+
+const (
+	t1 = 0x00 // 0000 0000
+	tx = 0x80 // 1000 0000
+	t2 = 0xC0 // 1100 0000
+	t3 = 0xE0 // 1110 0000
+	t4 = 0xF0 // 1111 0000
+	t5 = 0xF8 // 1111 1000
+
+	maskx = 0x3F // 0011 1111
+	mask2 = 0x1F // 0001 1111
+	mask3 = 0x0F // 0000 1111
+	mask4 = 0x07 // 0000 0111
+
+	rune1Max = 1<<7 - 1
+	rune2Max = 1<<11 - 1
+	rune3Max = 1<<16 - 1
+
+	surrogateMin = 0xD800
+	surrogateMax = 0xDFFF
+
+	maxRune   = '\U0010FFFF' // Maximum valid Unicode code point.
+	runeError = '\uFFFD'     // the "error" Rune or "Unicode replacement character"
+)
+
+func appendRune(p []byte, r rune) []byte {
+	// Negative values are erroneous. Making it unsigned addresses the problem.
+	switch i := uint32(r); {
+	case i <= rune1Max:
+		p = append(p, byte(r))
+		return p
+	case i <= rune2Max:
+		p = append(p, t2|byte(r>>6))
+		p = append(p, tx|byte(r)&maskx)
+		return p
+	case i > maxRune, surrogateMin <= i && i <= surrogateMax:
+		r = runeError
+		fallthrough
+	case i <= rune3Max:
+		p = append(p, t3|byte(r>>12))
+		p = append(p, tx|byte(r>>6)&maskx)
+		p = append(p, tx|byte(r)&maskx)
+		return p
+	default:
+		p = append(p, t4|byte(r>>18))
+		p = append(p, tx|byte(r>>12)&maskx)
+		p = append(p, tx|byte(r>>6)&maskx)
+		p = append(p, tx|byte(r)&maskx)
+		return p
+	}
+}

+ 18 - 0
vendor/github.com/json-iterator/go/jsoniter.go

@@ -0,0 +1,18 @@
+// Package jsoniter implements encoding and decoding of JSON as defined in
+// RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json.
+// Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter
+// and variable type declarations (if any).
+// jsoniter interfaces gives 100% compatibility with code using standard lib.
+//
+// "JSON and Go"
+// (https://golang.org/doc/articles/json_and_go.html)
+// gives a description of how Marshal/Unmarshal operate
+// between arbitrary or predefined json objects and bytes,
+// and it applies to jsoniter.Marshal/Unmarshal as well.
+//
+// Besides, jsoniter.Iterator provides a different set of interfaces
+// iterating given bytes/string/reader
+// and yielding parsed elements one by one.
+// This set of interfaces reads input as required and gives
+// better performance.
+package jsoniter

+ 42 - 0
vendor/github.com/json-iterator/go/pool.go

@@ -0,0 +1,42 @@
+package jsoniter
+
+import (
+	"io"
+)
+
+// IteratorPool a thread safe pool of iterators with same configuration
+type IteratorPool interface {
+	BorrowIterator(data []byte) *Iterator
+	ReturnIterator(iter *Iterator)
+}
+
+// StreamPool a thread safe pool of streams with same configuration
+type StreamPool interface {
+	BorrowStream(writer io.Writer) *Stream
+	ReturnStream(stream *Stream)
+}
+
+func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream {
+	stream := cfg.streamPool.Get().(*Stream)
+	stream.Reset(writer)
+	return stream
+}
+
+func (cfg *frozenConfig) ReturnStream(stream *Stream) {
+	stream.out = nil
+	stream.Error = nil
+	stream.Attachment = nil
+	cfg.streamPool.Put(stream)
+}
+
+func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator {
+	iter := cfg.iteratorPool.Get().(*Iterator)
+	iter.ResetBytes(data)
+	return iter
+}
+
+func (cfg *frozenConfig) ReturnIterator(iter *Iterator) {
+	iter.Error = nil
+	iter.Attachment = nil
+	cfg.iteratorPool.Put(iter)
+}

+ 332 - 0
vendor/github.com/json-iterator/go/reflect.go

@@ -0,0 +1,332 @@
+package jsoniter
+
+import (
+	"fmt"
+	"reflect"
+	"unsafe"
+
+	"github.com/modern-go/reflect2"
+)
+
+// ValDecoder is an internal type registered to cache as needed.
+// Don't confuse jsoniter.ValDecoder with json.Decoder.
+// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link).
+//
+// Reflection on type to create decoders, which is then cached
+// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions
+// 1. create instance of new value, for example *int will need a int to be allocated
+// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New
+// 3. assignment to map, both key and value will be reflect.Value
+// For a simple struct binding, it will be reflect.Value free and allocation free
+type ValDecoder interface {
+	Decode(ptr unsafe.Pointer, iter *Iterator)
+}
+
+// ValEncoder is an internal type registered to cache as needed.
+// Don't confuse jsoniter.ValEncoder with json.Encoder.
+// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link).
+type ValEncoder interface {
+	IsEmpty(ptr unsafe.Pointer) bool
+	Encode(ptr unsafe.Pointer, stream *Stream)
+}
+
+type checkIsEmpty interface {
+	IsEmpty(ptr unsafe.Pointer) bool
+}
+
+type ctx struct {
+	*frozenConfig
+	prefix   string
+	encoders map[reflect2.Type]ValEncoder
+	decoders map[reflect2.Type]ValDecoder
+}
+
+func (b *ctx) caseSensitive() bool {
+	if b.frozenConfig == nil {
+		// default is case-insensitive
+		return false
+	}
+	return b.frozenConfig.caseSensitive
+}
+
+func (b *ctx) append(prefix string) *ctx {
+	return &ctx{
+		frozenConfig: b.frozenConfig,
+		prefix:       b.prefix + " " + prefix,
+		encoders:     b.encoders,
+		decoders:     b.decoders,
+	}
+}
+
+// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal
+func (iter *Iterator) ReadVal(obj interface{}) {
+	cacheKey := reflect2.RTypeOf(obj)
+	decoder := iter.cfg.getDecoderFromCache(cacheKey)
+	if decoder == nil {
+		typ := reflect2.TypeOf(obj)
+		if typ.Kind() != reflect.Ptr {
+			iter.ReportError("ReadVal", "can only unmarshal into pointer")
+			return
+		}
+		decoder = iter.cfg.DecoderOf(typ)
+	}
+	ptr := reflect2.PtrOf(obj)
+	if ptr == nil {
+		iter.ReportError("ReadVal", "can not read into nil pointer")
+		return
+	}
+	decoder.Decode(ptr, iter)
+}
+
+// WriteVal copy the go interface into underlying JSON, same as json.Marshal
+func (stream *Stream) WriteVal(val interface{}) {
+	if nil == val {
+		stream.WriteNil()
+		return
+	}
+	cacheKey := reflect2.RTypeOf(val)
+	encoder := stream.cfg.getEncoderFromCache(cacheKey)
+	if encoder == nil {
+		typ := reflect2.TypeOf(val)
+		encoder = stream.cfg.EncoderOf(typ)
+	}
+	encoder.Encode(reflect2.PtrOf(val), stream)
+}
+
+func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder {
+	cacheKey := typ.RType()
+	decoder := cfg.getDecoderFromCache(cacheKey)
+	if decoder != nil {
+		return decoder
+	}
+	ctx := &ctx{
+		frozenConfig: cfg,
+		prefix:       "",
+		decoders:     map[reflect2.Type]ValDecoder{},
+		encoders:     map[reflect2.Type]ValEncoder{},
+	}
+	ptrType := typ.(*reflect2.UnsafePtrType)
+	decoder = decoderOfType(ctx, ptrType.Elem())
+	cfg.addDecoderToCache(cacheKey, decoder)
+	return decoder
+}
+
+func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
+	decoder := getTypeDecoderFromExtension(ctx, typ)
+	if decoder != nil {
+		return decoder
+	}
+	decoder = createDecoderOfType(ctx, typ)
+	for _, extension := range extensions {
+		decoder = extension.DecorateDecoder(typ, decoder)
+	}
+	decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder)
+	for _, extension := range ctx.extraExtensions {
+		decoder = extension.DecorateDecoder(typ, decoder)
+	}
+	return decoder
+}
+
+func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
+	decoder := ctx.decoders[typ]
+	if decoder != nil {
+		return decoder
+	}
+	placeholder := &placeholderDecoder{}
+	ctx.decoders[typ] = placeholder
+	decoder = _createDecoderOfType(ctx, typ)
+	placeholder.decoder = decoder
+	return decoder
+}
+
+func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
+	decoder := createDecoderOfJsonRawMessage(ctx, typ)
+	if decoder != nil {
+		return decoder
+	}
+	decoder = createDecoderOfJsonNumber(ctx, typ)
+	if decoder != nil {
+		return decoder
+	}
+	decoder = createDecoderOfMarshaler(ctx, typ)
+	if decoder != nil {
+		return decoder
+	}
+	decoder = createDecoderOfAny(ctx, typ)
+	if decoder != nil {
+		return decoder
+	}
+	decoder = createDecoderOfNative(ctx, typ)
+	if decoder != nil {
+		return decoder
+	}
+	switch typ.Kind() {
+	case reflect.Interface:
+		ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType)
+		if isIFace {
+			return &ifaceDecoder{valType: ifaceType}
+		}
+		return &efaceDecoder{}
+	case reflect.Struct:
+		return decoderOfStruct(ctx, typ)
+	case reflect.Array:
+		return decoderOfArray(ctx, typ)
+	case reflect.Slice:
+		return decoderOfSlice(ctx, typ)
+	case reflect.Map:
+		return decoderOfMap(ctx, typ)
+	case reflect.Ptr:
+		return decoderOfOptional(ctx, typ)
+	default:
+		return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())}
+	}
+}
+
+func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder {
+	cacheKey := typ.RType()
+	encoder := cfg.getEncoderFromCache(cacheKey)
+	if encoder != nil {
+		return encoder
+	}
+	ctx := &ctx{
+		frozenConfig: cfg,
+		prefix:       "",
+		decoders:     map[reflect2.Type]ValDecoder{},
+		encoders:     map[reflect2.Type]ValEncoder{},
+	}
+	encoder = encoderOfType(ctx, typ)
+	if typ.LikePtr() {
+		encoder = &onePtrEncoder{encoder}
+	}
+	cfg.addEncoderToCache(cacheKey, encoder)
+	return encoder
+}
+
+type onePtrEncoder struct {
+	encoder ValEncoder
+}
+
+func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr))
+}
+
+func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	encoder.encoder.Encode(unsafe.Pointer(&ptr), stream)
+}
+
+func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
+	encoder := getTypeEncoderFromExtension(ctx, typ)
+	if encoder != nil {
+		return encoder
+	}
+	encoder = createEncoderOfType(ctx, typ)
+	for _, extension := range extensions {
+		encoder = extension.DecorateEncoder(typ, encoder)
+	}
+	encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder)
+	for _, extension := range ctx.extraExtensions {
+		encoder = extension.DecorateEncoder(typ, encoder)
+	}
+	return encoder
+}
+
+func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
+	encoder := ctx.encoders[typ]
+	if encoder != nil {
+		return encoder
+	}
+	placeholder := &placeholderEncoder{}
+	ctx.encoders[typ] = placeholder
+	encoder = _createEncoderOfType(ctx, typ)
+	placeholder.encoder = encoder
+	return encoder
+}
+func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
+	encoder := createEncoderOfJsonRawMessage(ctx, typ)
+	if encoder != nil {
+		return encoder
+	}
+	encoder = createEncoderOfJsonNumber(ctx, typ)
+	if encoder != nil {
+		return encoder
+	}
+	encoder = createEncoderOfMarshaler(ctx, typ)
+	if encoder != nil {
+		return encoder
+	}
+	encoder = createEncoderOfAny(ctx, typ)
+	if encoder != nil {
+		return encoder
+	}
+	encoder = createEncoderOfNative(ctx, typ)
+	if encoder != nil {
+		return encoder
+	}
+	kind := typ.Kind()
+	switch kind {
+	case reflect.Interface:
+		return &dynamicEncoder{typ}
+	case reflect.Struct:
+		return encoderOfStruct(ctx, typ)
+	case reflect.Array:
+		return encoderOfArray(ctx, typ)
+	case reflect.Slice:
+		return encoderOfSlice(ctx, typ)
+	case reflect.Map:
+		return encoderOfMap(ctx, typ)
+	case reflect.Ptr:
+		return encoderOfOptional(ctx, typ)
+	default:
+		return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())}
+	}
+}
+
+type lazyErrorDecoder struct {
+	err error
+}
+
+func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if iter.WhatIsNext() != NilValue {
+		if iter.Error == nil {
+			iter.Error = decoder.err
+		}
+	} else {
+		iter.Skip()
+	}
+}
+
+type lazyErrorEncoder struct {
+	err error
+}
+
+func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	if ptr == nil {
+		stream.WriteNil()
+	} else if stream.Error == nil {
+		stream.Error = encoder.err
+	}
+}
+
+func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return false
+}
+
+type placeholderDecoder struct {
+	decoder ValDecoder
+}
+
+func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.decoder.Decode(ptr, iter)
+}
+
+type placeholderEncoder struct {
+	encoder ValEncoder
+}
+
+func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	encoder.encoder.Encode(ptr, stream)
+}
+
+func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.encoder.IsEmpty(ptr)
+}

+ 104 - 0
vendor/github.com/json-iterator/go/reflect_array.go

@@ -0,0 +1,104 @@
+package jsoniter
+
+import (
+	"fmt"
+	"github.com/modern-go/reflect2"
+	"io"
+	"unsafe"
+)
+
+func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
+	arrayType := typ.(*reflect2.UnsafeArrayType)
+	decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
+	return &arrayDecoder{arrayType, decoder}
+}
+
+func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder {
+	arrayType := typ.(*reflect2.UnsafeArrayType)
+	if arrayType.Len() == 0 {
+		return emptyArrayEncoder{}
+	}
+	encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
+	return &arrayEncoder{arrayType, encoder}
+}
+
+type emptyArrayEncoder struct{}
+
+func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteEmptyArray()
+}
+
+func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return true
+}
+
+type arrayEncoder struct {
+	arrayType   *reflect2.UnsafeArrayType
+	elemEncoder ValEncoder
+}
+
+func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteArrayStart()
+	elemPtr := unsafe.Pointer(ptr)
+	encoder.elemEncoder.Encode(elemPtr, stream)
+	for i := 1; i < encoder.arrayType.Len(); i++ {
+		stream.WriteMore()
+		elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i)
+		encoder.elemEncoder.Encode(elemPtr, stream)
+	}
+	stream.WriteArrayEnd()
+	if stream.Error != nil && stream.Error != io.EOF {
+		stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
+	}
+}
+
+func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return false
+}
+
+type arrayDecoder struct {
+	arrayType   *reflect2.UnsafeArrayType
+	elemDecoder ValDecoder
+}
+
+func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.doDecode(ptr, iter)
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
+	}
+}
+
+func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
+	c := iter.nextToken()
+	arrayType := decoder.arrayType
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		return
+	}
+	if c != '[' {
+		iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
+		return
+	}
+	c = iter.nextToken()
+	if c == ']' {
+		return
+	}
+	iter.unreadByte()
+	elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
+	decoder.elemDecoder.Decode(elemPtr, iter)
+	length := 1
+	for c = iter.nextToken(); c == ','; c = iter.nextToken() {
+		if length >= arrayType.Len() {
+			iter.Skip()
+			continue
+		}
+		idx := length
+		length += 1
+		elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
+		decoder.elemDecoder.Decode(elemPtr, iter)
+	}
+	if c != ']' {
+		iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
+		return
+	}
+}

+ 70 - 0
vendor/github.com/json-iterator/go/reflect_dynamic.go

@@ -0,0 +1,70 @@
+package jsoniter
+
+import (
+	"github.com/modern-go/reflect2"
+	"reflect"
+	"unsafe"
+)
+
+type dynamicEncoder struct {
+	valType reflect2.Type
+}
+
+func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	obj := encoder.valType.UnsafeIndirect(ptr)
+	stream.WriteVal(obj)
+}
+
+func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.valType.UnsafeIndirect(ptr) == nil
+}
+
+type efaceDecoder struct {
+}
+
+func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	pObj := (*interface{})(ptr)
+	obj := *pObj
+	if obj == nil {
+		*pObj = iter.Read()
+		return
+	}
+	typ := reflect2.TypeOf(obj)
+	if typ.Kind() != reflect.Ptr {
+		*pObj = iter.Read()
+		return
+	}
+	ptrType := typ.(*reflect2.UnsafePtrType)
+	ptrElemType := ptrType.Elem()
+	if iter.WhatIsNext() == NilValue {
+		if ptrElemType.Kind() != reflect.Ptr {
+			iter.skipFourBytes('n', 'u', 'l', 'l')
+			*pObj = nil
+			return
+		}
+	}
+	if reflect2.IsNil(obj) {
+		obj := ptrElemType.New()
+		iter.ReadVal(obj)
+		*pObj = obj
+		return
+	}
+	iter.ReadVal(obj)
+}
+
+type ifaceDecoder struct {
+	valType *reflect2.UnsafeIFaceType
+}
+
+func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if iter.ReadNil() {
+		decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew())
+		return
+	}
+	obj := decoder.valType.UnsafeIndirect(ptr)
+	if reflect2.IsNil(obj) {
+		iter.ReportError("decode non empty interface", "can not unmarshal into nil")
+		return
+	}
+	iter.ReadVal(obj)
+}

+ 483 - 0
vendor/github.com/json-iterator/go/reflect_extension.go

@@ -0,0 +1,483 @@
+package jsoniter
+
+import (
+	"fmt"
+	"github.com/modern-go/reflect2"
+	"reflect"
+	"sort"
+	"strings"
+	"unicode"
+	"unsafe"
+)
+
+var typeDecoders = map[string]ValDecoder{}
+var fieldDecoders = map[string]ValDecoder{}
+var typeEncoders = map[string]ValEncoder{}
+var fieldEncoders = map[string]ValEncoder{}
+var extensions = []Extension{}
+
+// StructDescriptor describe how should we encode/decode the struct
+type StructDescriptor struct {
+	Type   reflect2.Type
+	Fields []*Binding
+}
+
+// GetField get one field from the descriptor by its name.
+// Can not use map here to keep field orders.
+func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding {
+	for _, binding := range structDescriptor.Fields {
+		if binding.Field.Name() == fieldName {
+			return binding
+		}
+	}
+	return nil
+}
+
+// Binding describe how should we encode/decode the struct field
+type Binding struct {
+	levels    []int
+	Field     reflect2.StructField
+	FromNames []string
+	ToNames   []string
+	Encoder   ValEncoder
+	Decoder   ValDecoder
+}
+
+// Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder.
+// Can also rename fields by UpdateStructDescriptor.
+type Extension interface {
+	UpdateStructDescriptor(structDescriptor *StructDescriptor)
+	CreateMapKeyDecoder(typ reflect2.Type) ValDecoder
+	CreateMapKeyEncoder(typ reflect2.Type) ValEncoder
+	CreateDecoder(typ reflect2.Type) ValDecoder
+	CreateEncoder(typ reflect2.Type) ValEncoder
+	DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder
+	DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder
+}
+
+// DummyExtension embed this type get dummy implementation for all methods of Extension
+type DummyExtension struct {
+}
+
+// UpdateStructDescriptor No-op
+func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
+}
+
+// CreateMapKeyDecoder No-op
+func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
+	return nil
+}
+
+// CreateMapKeyEncoder No-op
+func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
+	return nil
+}
+
+// CreateDecoder No-op
+func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
+	return nil
+}
+
+// CreateEncoder No-op
+func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
+	return nil
+}
+
+// DecorateDecoder No-op
+func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
+	return decoder
+}
+
+// DecorateEncoder No-op
+func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
+	return encoder
+}
+
+type EncoderExtension map[reflect2.Type]ValEncoder
+
+// UpdateStructDescriptor No-op
+func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
+}
+
+// CreateDecoder No-op
+func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
+	return nil
+}
+
+// CreateEncoder get encoder from map
+func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
+	return extension[typ]
+}
+
+// CreateMapKeyDecoder No-op
+func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
+	return nil
+}
+
+// CreateMapKeyEncoder No-op
+func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
+	return nil
+}
+
+// DecorateDecoder No-op
+func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
+	return decoder
+}
+
+// DecorateEncoder No-op
+func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
+	return encoder
+}
+
+type DecoderExtension map[reflect2.Type]ValDecoder
+
+// UpdateStructDescriptor No-op
+func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
+}
+
+// CreateMapKeyDecoder No-op
+func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
+	return nil
+}
+
+// CreateMapKeyEncoder No-op
+func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
+	return nil
+}
+
+// CreateDecoder get decoder from map
+func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
+	return extension[typ]
+}
+
+// CreateEncoder No-op
+func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
+	return nil
+}
+
+// DecorateDecoder No-op
+func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
+	return decoder
+}
+
+// DecorateEncoder No-op
+func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
+	return encoder
+}
+
+type funcDecoder struct {
+	fun DecoderFunc
+}
+
+func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.fun(ptr, iter)
+}
+
+type funcEncoder struct {
+	fun         EncoderFunc
+	isEmptyFunc func(ptr unsafe.Pointer) bool
+}
+
+func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	encoder.fun(ptr, stream)
+}
+
+func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	if encoder.isEmptyFunc == nil {
+		return false
+	}
+	return encoder.isEmptyFunc(ptr)
+}
+
+// DecoderFunc the function form of TypeDecoder
+type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
+
+// EncoderFunc the function form of TypeEncoder
+type EncoderFunc func(ptr unsafe.Pointer, stream *Stream)
+
+// RegisterTypeDecoderFunc register TypeDecoder for a type with function
+func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) {
+	typeDecoders[typ] = &funcDecoder{fun}
+}
+
+// RegisterTypeDecoder register TypeDecoder for a typ
+func RegisterTypeDecoder(typ string, decoder ValDecoder) {
+	typeDecoders[typ] = decoder
+}
+
+// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function
+func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) {
+	RegisterFieldDecoder(typ, field, &funcDecoder{fun})
+}
+
+// RegisterFieldDecoder register TypeDecoder for a struct field
+func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) {
+	fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder
+}
+
+// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function
+func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) {
+	typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc}
+}
+
+// RegisterTypeEncoder register TypeEncoder for a type
+func RegisterTypeEncoder(typ string, encoder ValEncoder) {
+	typeEncoders[typ] = encoder
+}
+
+// RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function
+func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) {
+	RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc})
+}
+
+// RegisterFieldEncoder register TypeEncoder for a struct field
+func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) {
+	fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder
+}
+
+// RegisterExtension register extension
+func RegisterExtension(extension Extension) {
+	extensions = append(extensions, extension)
+}
+
+func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
+	decoder := _getTypeDecoderFromExtension(ctx, typ)
+	if decoder != nil {
+		for _, extension := range extensions {
+			decoder = extension.DecorateDecoder(typ, decoder)
+		}
+		decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder)
+		for _, extension := range ctx.extraExtensions {
+			decoder = extension.DecorateDecoder(typ, decoder)
+		}
+	}
+	return decoder
+}
+func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
+	for _, extension := range extensions {
+		decoder := extension.CreateDecoder(typ)
+		if decoder != nil {
+			return decoder
+		}
+	}
+	decoder := ctx.decoderExtension.CreateDecoder(typ)
+	if decoder != nil {
+		return decoder
+	}
+	for _, extension := range ctx.extraExtensions {
+		decoder := extension.CreateDecoder(typ)
+		if decoder != nil {
+			return decoder
+		}
+	}
+	typeName := typ.String()
+	decoder = typeDecoders[typeName]
+	if decoder != nil {
+		return decoder
+	}
+	if typ.Kind() == reflect.Ptr {
+		ptrType := typ.(*reflect2.UnsafePtrType)
+		decoder := typeDecoders[ptrType.Elem().String()]
+		if decoder != nil {
+			return &OptionalDecoder{ptrType.Elem(), decoder}
+		}
+	}
+	return nil
+}
+
+func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
+	encoder := _getTypeEncoderFromExtension(ctx, typ)
+	if encoder != nil {
+		for _, extension := range extensions {
+			encoder = extension.DecorateEncoder(typ, encoder)
+		}
+		encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder)
+		for _, extension := range ctx.extraExtensions {
+			encoder = extension.DecorateEncoder(typ, encoder)
+		}
+	}
+	return encoder
+}
+
+func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
+	for _, extension := range extensions {
+		encoder := extension.CreateEncoder(typ)
+		if encoder != nil {
+			return encoder
+		}
+	}
+	encoder := ctx.encoderExtension.CreateEncoder(typ)
+	if encoder != nil {
+		return encoder
+	}
+	for _, extension := range ctx.extraExtensions {
+		encoder := extension.CreateEncoder(typ)
+		if encoder != nil {
+			return encoder
+		}
+	}
+	typeName := typ.String()
+	encoder = typeEncoders[typeName]
+	if encoder != nil {
+		return encoder
+	}
+	if typ.Kind() == reflect.Ptr {
+		typePtr := typ.(*reflect2.UnsafePtrType)
+		encoder := typeEncoders[typePtr.Elem().String()]
+		if encoder != nil {
+			return &OptionalEncoder{encoder}
+		}
+	}
+	return nil
+}
+
+func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor {
+	structType := typ.(*reflect2.UnsafeStructType)
+	embeddedBindings := []*Binding{}
+	bindings := []*Binding{}
+	for i := 0; i < structType.NumField(); i++ {
+		field := structType.Field(i)
+		tag, hastag := field.Tag().Lookup(ctx.getTagKey())
+		if ctx.onlyTaggedField && !hastag {
+			continue
+		}
+		tagParts := strings.Split(tag, ",")
+		if tag == "-" {
+			continue
+		}
+		if field.Anonymous() && (tag == "" || tagParts[0] == "") {
+			if field.Type().Kind() == reflect.Struct {
+				structDescriptor := describeStruct(ctx, field.Type())
+				for _, binding := range structDescriptor.Fields {
+					binding.levels = append([]int{i}, binding.levels...)
+					omitempty := binding.Encoder.(*structFieldEncoder).omitempty
+					binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}
+					binding.Decoder = &structFieldDecoder{field, binding.Decoder}
+					embeddedBindings = append(embeddedBindings, binding)
+				}
+				continue
+			} else if field.Type().Kind() == reflect.Ptr {
+				ptrType := field.Type().(*reflect2.UnsafePtrType)
+				if ptrType.Elem().Kind() == reflect.Struct {
+					structDescriptor := describeStruct(ctx, ptrType.Elem())
+					for _, binding := range structDescriptor.Fields {
+						binding.levels = append([]int{i}, binding.levels...)
+						omitempty := binding.Encoder.(*structFieldEncoder).omitempty
+						binding.Encoder = &dereferenceEncoder{binding.Encoder}
+						binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}
+						binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder}
+						binding.Decoder = &structFieldDecoder{field, binding.Decoder}
+						embeddedBindings = append(embeddedBindings, binding)
+					}
+					continue
+				}
+			}
+		}
+		fieldNames := calcFieldNames(field.Name(), tagParts[0], tag)
+		fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name())
+		decoder := fieldDecoders[fieldCacheKey]
+		if decoder == nil {
+			decoder = decoderOfType(ctx.append(field.Name()), field.Type())
+		}
+		encoder := fieldEncoders[fieldCacheKey]
+		if encoder == nil {
+			encoder = encoderOfType(ctx.append(field.Name()), field.Type())
+		}
+		binding := &Binding{
+			Field:     field,
+			FromNames: fieldNames,
+			ToNames:   fieldNames,
+			Decoder:   decoder,
+			Encoder:   encoder,
+		}
+		binding.levels = []int{i}
+		bindings = append(bindings, binding)
+	}
+	return createStructDescriptor(ctx, typ, bindings, embeddedBindings)
+}
+func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
+	structDescriptor := &StructDescriptor{
+		Type:   typ,
+		Fields: bindings,
+	}
+	for _, extension := range extensions {
+		extension.UpdateStructDescriptor(structDescriptor)
+	}
+	ctx.encoderExtension.UpdateStructDescriptor(structDescriptor)
+	ctx.decoderExtension.UpdateStructDescriptor(structDescriptor)
+	for _, extension := range ctx.extraExtensions {
+		extension.UpdateStructDescriptor(structDescriptor)
+	}
+	processTags(structDescriptor, ctx.frozenConfig)
+	// merge normal & embedded bindings & sort with original order
+	allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...))
+	sort.Sort(allBindings)
+	structDescriptor.Fields = allBindings
+	return structDescriptor
+}
+
+type sortableBindings []*Binding
+
+func (bindings sortableBindings) Len() int {
+	return len(bindings)
+}
+
+func (bindings sortableBindings) Less(i, j int) bool {
+	left := bindings[i].levels
+	right := bindings[j].levels
+	k := 0
+	for {
+		if left[k] < right[k] {
+			return true
+		} else if left[k] > right[k] {
+			return false
+		}
+		k++
+	}
+}
+
+func (bindings sortableBindings) Swap(i, j int) {
+	bindings[i], bindings[j] = bindings[j], bindings[i]
+}
+
+func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) {
+	for _, binding := range structDescriptor.Fields {
+		shouldOmitEmpty := false
+		tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",")
+		for _, tagPart := range tagParts[1:] {
+			if tagPart == "omitempty" {
+				shouldOmitEmpty = true
+			} else if tagPart == "string" {
+				if binding.Field.Type().Kind() == reflect.String {
+					binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg}
+					binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg}
+				} else {
+					binding.Decoder = &stringModeNumberDecoder{binding.Decoder}
+					binding.Encoder = &stringModeNumberEncoder{binding.Encoder}
+				}
+			}
+		}
+		binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder}
+		binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty}
+	}
+}
+
+func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string {
+	// ignore?
+	if wholeTag == "-" {
+		return []string{}
+	}
+	// rename?
+	var fieldNames []string
+	if tagProvidedFieldName == "" {
+		fieldNames = []string{originalFieldName}
+	} else {
+		fieldNames = []string{tagProvidedFieldName}
+	}
+	// private?
+	isNotExported := unicode.IsLower(rune(originalFieldName[0]))
+	if isNotExported {
+		fieldNames = []string{}
+	}
+	return fieldNames
+}

+ 112 - 0
vendor/github.com/json-iterator/go/reflect_json_number.go

@@ -0,0 +1,112 @@
+package jsoniter
+
+import (
+	"encoding/json"
+	"github.com/modern-go/reflect2"
+	"strconv"
+	"unsafe"
+)
+
+type Number string
+
+// String returns the literal text of the number.
+func (n Number) String() string { return string(n) }
+
+// Float64 returns the number as a float64.
+func (n Number) Float64() (float64, error) {
+	return strconv.ParseFloat(string(n), 64)
+}
+
+// Int64 returns the number as an int64.
+func (n Number) Int64() (int64, error) {
+	return strconv.ParseInt(string(n), 10, 64)
+}
+
+func CastJsonNumber(val interface{}) (string, bool) {
+	switch typedVal := val.(type) {
+	case json.Number:
+		return string(typedVal), true
+	case Number:
+		return string(typedVal), true
+	}
+	return "", false
+}
+
+var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem()
+var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem()
+
+func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder {
+	if typ.AssignableTo(jsonNumberType) {
+		return &jsonNumberCodec{}
+	}
+	if typ.AssignableTo(jsoniterNumberType) {
+		return &jsoniterNumberCodec{}
+	}
+	return nil
+}
+
+func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder {
+	if typ.AssignableTo(jsonNumberType) {
+		return &jsonNumberCodec{}
+	}
+	if typ.AssignableTo(jsoniterNumberType) {
+		return &jsoniterNumberCodec{}
+	}
+	return nil
+}
+
+type jsonNumberCodec struct {
+}
+
+func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	switch iter.WhatIsNext() {
+	case StringValue:
+		*((*json.Number)(ptr)) = json.Number(iter.ReadString())
+	case NilValue:
+		iter.skipFourBytes('n', 'u', 'l', 'l')
+		*((*json.Number)(ptr)) = ""
+	default:
+		*((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString()))
+	}
+}
+
+func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	number := *((*json.Number)(ptr))
+	if len(number) == 0 {
+		stream.writeByte('0')
+	} else {
+		stream.WriteRaw(string(number))
+	}
+}
+
+func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*json.Number)(ptr))) == 0
+}
+
+type jsoniterNumberCodec struct {
+}
+
+func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	switch iter.WhatIsNext() {
+	case StringValue:
+		*((*Number)(ptr)) = Number(iter.ReadString())
+	case NilValue:
+		iter.skipFourBytes('n', 'u', 'l', 'l')
+		*((*Number)(ptr)) = ""
+	default:
+		*((*Number)(ptr)) = Number([]byte(iter.readNumberAsString()))
+	}
+}
+
+func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	number := *((*Number)(ptr))
+	if len(number) == 0 {
+		stream.writeByte('0')
+	} else {
+		stream.WriteRaw(string(number))
+	}
+}
+
+func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*Number)(ptr))) == 0
+}

+ 60 - 0
vendor/github.com/json-iterator/go/reflect_json_raw_message.go

@@ -0,0 +1,60 @@
+package jsoniter
+
+import (
+	"encoding/json"
+	"github.com/modern-go/reflect2"
+	"unsafe"
+)
+
+var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()
+var jsoniterRawMessageType = reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()
+
+func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValEncoder {
+	if typ == jsonRawMessageType {
+		return &jsonRawMessageCodec{}
+	}
+	if typ == jsoniterRawMessageType {
+		return &jsoniterRawMessageCodec{}
+	}
+	return nil
+}
+
+func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValDecoder {
+	if typ == jsonRawMessageType {
+		return &jsonRawMessageCodec{}
+	}
+	if typ == jsoniterRawMessageType {
+		return &jsoniterRawMessageCodec{}
+	}
+	return nil
+}
+
+type jsonRawMessageCodec struct {
+}
+
+func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes())
+}
+
+func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteRaw(string(*((*json.RawMessage)(ptr))))
+}
+
+func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*json.RawMessage)(ptr))) == 0
+}
+
+type jsoniterRawMessageCodec struct {
+}
+
+func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes())
+}
+
+func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteRaw(string(*((*RawMessage)(ptr))))
+}
+
+func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*RawMessage)(ptr))) == 0
+}

+ 326 - 0
vendor/github.com/json-iterator/go/reflect_map.go

@@ -0,0 +1,326 @@
+package jsoniter
+
+import (
+	"fmt"
+	"github.com/modern-go/reflect2"
+	"io"
+	"reflect"
+	"sort"
+	"unsafe"
+)
+
+func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder {
+	mapType := typ.(*reflect2.UnsafeMapType)
+	keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key())
+	elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem())
+	return &mapDecoder{
+		mapType:     mapType,
+		keyType:     mapType.Key(),
+		elemType:    mapType.Elem(),
+		keyDecoder:  keyDecoder,
+		elemDecoder: elemDecoder,
+	}
+}
+
+func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder {
+	mapType := typ.(*reflect2.UnsafeMapType)
+	if ctx.sortMapKeys {
+		return &sortKeysMapEncoder{
+			mapType:     mapType,
+			keyEncoder:  encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
+			elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
+		}
+	}
+	return &mapEncoder{
+		mapType:     mapType,
+		keyEncoder:  encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
+		elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
+	}
+}
+
+func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
+	decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ)
+	if decoder != nil {
+		return decoder
+	}
+	for _, extension := range ctx.extraExtensions {
+		decoder := extension.CreateMapKeyDecoder(typ)
+		if decoder != nil {
+			return decoder
+		}
+	}
+	switch typ.Kind() {
+	case reflect.String:
+		return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
+	case reflect.Bool,
+		reflect.Uint8, reflect.Int8,
+		reflect.Uint16, reflect.Int16,
+		reflect.Uint32, reflect.Int32,
+		reflect.Uint64, reflect.Int64,
+		reflect.Uint, reflect.Int,
+		reflect.Float32, reflect.Float64,
+		reflect.Uintptr:
+		typ = reflect2.DefaultTypeOfKind(typ.Kind())
+		return &numericMapKeyDecoder{decoderOfType(ctx, typ)}
+	default:
+		ptrType := reflect2.PtrTo(typ)
+		if ptrType.Implements(textMarshalerType) {
+			return &referenceDecoder{
+				&textUnmarshalerDecoder{
+					valType: ptrType,
+				},
+			}
+		}
+		if typ.Implements(textMarshalerType) {
+			return &textUnmarshalerDecoder{
+				valType: typ,
+			}
+		}
+		return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
+	}
+}
+
+func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
+	encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ)
+	if encoder != nil {
+		return encoder
+	}
+	for _, extension := range ctx.extraExtensions {
+		encoder := extension.CreateMapKeyEncoder(typ)
+		if encoder != nil {
+			return encoder
+		}
+	}
+	switch typ.Kind() {
+	case reflect.String:
+		return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
+	case reflect.Bool,
+		reflect.Uint8, reflect.Int8,
+		reflect.Uint16, reflect.Int16,
+		reflect.Uint32, reflect.Int32,
+		reflect.Uint64, reflect.Int64,
+		reflect.Uint, reflect.Int,
+		reflect.Float32, reflect.Float64,
+		reflect.Uintptr:
+		typ = reflect2.DefaultTypeOfKind(typ.Kind())
+		return &numericMapKeyEncoder{encoderOfType(ctx, typ)}
+	default:
+		if typ == textMarshalerType {
+			return &directTextMarshalerEncoder{
+				stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
+			}
+		}
+		if typ.Implements(textMarshalerType) {
+			return &textMarshalerEncoder{
+				valType:       typ,
+				stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
+			}
+		}
+		if typ.Kind() == reflect.Interface {
+			return &dynamicMapKeyEncoder{ctx, typ}
+		}
+		return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
+	}
+}
+
+type mapDecoder struct {
+	mapType     *reflect2.UnsafeMapType
+	keyType     reflect2.Type
+	elemType    reflect2.Type
+	keyDecoder  ValDecoder
+	elemDecoder ValDecoder
+}
+
+func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	mapType := decoder.mapType
+	c := iter.nextToken()
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		*(*unsafe.Pointer)(ptr) = nil
+		mapType.UnsafeSet(ptr, mapType.UnsafeNew())
+		return
+	}
+	if mapType.UnsafeIsNil(ptr) {
+		mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0))
+	}
+	if c != '{' {
+		iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
+		return
+	}
+	c = iter.nextToken()
+	if c == '}' {
+		return
+	}
+	if c != '"' {
+		iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
+		return
+	}
+	iter.unreadByte()
+	key := decoder.keyType.UnsafeNew()
+	decoder.keyDecoder.Decode(key, iter)
+	c = iter.nextToken()
+	if c != ':' {
+		iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
+		return
+	}
+	elem := decoder.elemType.UnsafeNew()
+	decoder.elemDecoder.Decode(elem, iter)
+	decoder.mapType.UnsafeSetIndex(ptr, key, elem)
+	for c = iter.nextToken(); c == ','; c = iter.nextToken() {
+		key := decoder.keyType.UnsafeNew()
+		decoder.keyDecoder.Decode(key, iter)
+		c = iter.nextToken()
+		if c != ':' {
+			iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
+			return
+		}
+		elem := decoder.elemType.UnsafeNew()
+		decoder.elemDecoder.Decode(elem, iter)
+		decoder.mapType.UnsafeSetIndex(ptr, key, elem)
+	}
+	if c != '}' {
+		iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c}))
+	}
+}
+
+type numericMapKeyDecoder struct {
+	decoder ValDecoder
+}
+
+func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	c := iter.nextToken()
+	if c != '"' {
+		iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
+		return
+	}
+	decoder.decoder.Decode(ptr, iter)
+	c = iter.nextToken()
+	if c != '"' {
+		iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
+		return
+	}
+}
+
+type numericMapKeyEncoder struct {
+	encoder ValEncoder
+}
+
+func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.writeByte('"')
+	encoder.encoder.Encode(ptr, stream)
+	stream.writeByte('"')
+}
+
+func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return false
+}
+
+type dynamicMapKeyEncoder struct {
+	ctx     *ctx
+	valType reflect2.Type
+}
+
+func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	obj := encoder.valType.UnsafeIndirect(ptr)
+	encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream)
+}
+
+func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	obj := encoder.valType.UnsafeIndirect(ptr)
+	return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj))
+}
+
+type mapEncoder struct {
+	mapType     *reflect2.UnsafeMapType
+	keyEncoder  ValEncoder
+	elemEncoder ValEncoder
+}
+
+func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteObjectStart()
+	iter := encoder.mapType.UnsafeIterate(ptr)
+	for i := 0; iter.HasNext(); i++ {
+		if i != 0 {
+			stream.WriteMore()
+		}
+		key, elem := iter.UnsafeNext()
+		encoder.keyEncoder.Encode(key, stream)
+		if stream.indention > 0 {
+			stream.writeTwoBytes(byte(':'), byte(' '))
+		} else {
+			stream.writeByte(':')
+		}
+		encoder.elemEncoder.Encode(elem, stream)
+	}
+	stream.WriteObjectEnd()
+}
+
+func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	iter := encoder.mapType.UnsafeIterate(ptr)
+	return !iter.HasNext()
+}
+
+type sortKeysMapEncoder struct {
+	mapType     *reflect2.UnsafeMapType
+	keyEncoder  ValEncoder
+	elemEncoder ValEncoder
+}
+
+func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	if *(*unsafe.Pointer)(ptr) == nil {
+		stream.WriteNil()
+		return
+	}
+	stream.WriteObjectStart()
+	mapIter := encoder.mapType.UnsafeIterate(ptr)
+	subStream := stream.cfg.BorrowStream(nil)
+	subIter := stream.cfg.BorrowIterator(nil)
+	keyValues := encodedKeyValues{}
+	for mapIter.HasNext() {
+		subStream.buf = make([]byte, 0, 64)
+		key, elem := mapIter.UnsafeNext()
+		encoder.keyEncoder.Encode(key, subStream)
+		if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil {
+			stream.Error = subStream.Error
+		}
+		encodedKey := subStream.Buffer()
+		subIter.ResetBytes(encodedKey)
+		decodedKey := subIter.ReadString()
+		if stream.indention > 0 {
+			subStream.writeTwoBytes(byte(':'), byte(' '))
+		} else {
+			subStream.writeByte(':')
+		}
+		encoder.elemEncoder.Encode(elem, subStream)
+		keyValues = append(keyValues, encodedKV{
+			key:      decodedKey,
+			keyValue: subStream.Buffer(),
+		})
+	}
+	sort.Sort(keyValues)
+	for i, keyValue := range keyValues {
+		if i != 0 {
+			stream.WriteMore()
+		}
+		stream.Write(keyValue.keyValue)
+	}
+	stream.WriteObjectEnd()
+	stream.cfg.ReturnStream(subStream)
+	stream.cfg.ReturnIterator(subIter)
+}
+
+func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	iter := encoder.mapType.UnsafeIterate(ptr)
+	return !iter.HasNext()
+}
+
+type encodedKeyValues []encodedKV
+
+type encodedKV struct {
+	key      string
+	keyValue []byte
+}
+
+func (sv encodedKeyValues) Len() int           { return len(sv) }
+func (sv encodedKeyValues) Swap(i, j int)      { sv[i], sv[j] = sv[j], sv[i] }
+func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }

+ 218 - 0
vendor/github.com/json-iterator/go/reflect_marshaler.go

@@ -0,0 +1,218 @@
+package jsoniter
+
+import (
+	"encoding"
+	"encoding/json"
+	"github.com/modern-go/reflect2"
+	"unsafe"
+)
+
+var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem()
+var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem()
+var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem()
+var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem()
+
+func createDecoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValDecoder {
+	ptrType := reflect2.PtrTo(typ)
+	if ptrType.Implements(unmarshalerType) {
+		return &referenceDecoder{
+			&unmarshalerDecoder{ptrType},
+		}
+	}
+	if ptrType.Implements(textUnmarshalerType) {
+		return &referenceDecoder{
+			&textUnmarshalerDecoder{ptrType},
+		}
+	}
+	return nil
+}
+
+func createEncoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValEncoder {
+	if typ == marshalerType {
+		checkIsEmpty := createCheckIsEmpty(ctx, typ)
+		var encoder ValEncoder = &directMarshalerEncoder{
+			checkIsEmpty: checkIsEmpty,
+		}
+		return encoder
+	}
+	if typ.Implements(marshalerType) {
+		checkIsEmpty := createCheckIsEmpty(ctx, typ)
+		var encoder ValEncoder = &marshalerEncoder{
+			valType:      typ,
+			checkIsEmpty: checkIsEmpty,
+		}
+		return encoder
+	}
+	ptrType := reflect2.PtrTo(typ)
+	if ctx.prefix != "" && ptrType.Implements(marshalerType) {
+		checkIsEmpty := createCheckIsEmpty(ctx, ptrType)
+		var encoder ValEncoder = &marshalerEncoder{
+			valType:      ptrType,
+			checkIsEmpty: checkIsEmpty,
+		}
+		return &referenceEncoder{encoder}
+	}
+	if typ == textMarshalerType {
+		checkIsEmpty := createCheckIsEmpty(ctx, typ)
+		var encoder ValEncoder = &directTextMarshalerEncoder{
+			checkIsEmpty:  checkIsEmpty,
+			stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
+		}
+		return encoder
+	}
+	if typ.Implements(textMarshalerType) {
+		checkIsEmpty := createCheckIsEmpty(ctx, typ)
+		var encoder ValEncoder = &textMarshalerEncoder{
+			valType:       typ,
+			stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
+			checkIsEmpty:  checkIsEmpty,
+		}
+		return encoder
+	}
+	// if prefix is empty, the type is the root type
+	if ctx.prefix != "" && ptrType.Implements(textMarshalerType) {
+		checkIsEmpty := createCheckIsEmpty(ctx, ptrType)
+		var encoder ValEncoder = &textMarshalerEncoder{
+			valType:       ptrType,
+			stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
+			checkIsEmpty:  checkIsEmpty,
+		}
+		return &referenceEncoder{encoder}
+	}
+	return nil
+}
+
+type marshalerEncoder struct {
+	checkIsEmpty checkIsEmpty
+	valType      reflect2.Type
+}
+
+func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	obj := encoder.valType.UnsafeIndirect(ptr)
+	if encoder.valType.IsNullable() && reflect2.IsNil(obj) {
+		stream.WriteNil()
+		return
+	}
+	marshaler := obj.(json.Marshaler)
+	bytes, err := marshaler.MarshalJSON()
+	if err != nil {
+		stream.Error = err
+	} else {
+		stream.Write(bytes)
+	}
+}
+
+func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.checkIsEmpty.IsEmpty(ptr)
+}
+
+type directMarshalerEncoder struct {
+	checkIsEmpty checkIsEmpty
+}
+
+func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	marshaler := *(*json.Marshaler)(ptr)
+	if marshaler == nil {
+		stream.WriteNil()
+		return
+	}
+	bytes, err := marshaler.MarshalJSON()
+	if err != nil {
+		stream.Error = err
+	} else {
+		stream.Write(bytes)
+	}
+}
+
+func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.checkIsEmpty.IsEmpty(ptr)
+}
+
+type textMarshalerEncoder struct {
+	valType       reflect2.Type
+	stringEncoder ValEncoder
+	checkIsEmpty  checkIsEmpty
+}
+
+func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	obj := encoder.valType.UnsafeIndirect(ptr)
+	if encoder.valType.IsNullable() && reflect2.IsNil(obj) {
+		stream.WriteNil()
+		return
+	}
+	marshaler := (obj).(encoding.TextMarshaler)
+	bytes, err := marshaler.MarshalText()
+	if err != nil {
+		stream.Error = err
+	} else {
+		str := string(bytes)
+		encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream)
+	}
+}
+
+func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.checkIsEmpty.IsEmpty(ptr)
+}
+
+type directTextMarshalerEncoder struct {
+	stringEncoder ValEncoder
+	checkIsEmpty  checkIsEmpty
+}
+
+func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	marshaler := *(*encoding.TextMarshaler)(ptr)
+	if marshaler == nil {
+		stream.WriteNil()
+		return
+	}
+	bytes, err := marshaler.MarshalText()
+	if err != nil {
+		stream.Error = err
+	} else {
+		str := string(bytes)
+		encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream)
+	}
+}
+
+func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.checkIsEmpty.IsEmpty(ptr)
+}
+
+type unmarshalerDecoder struct {
+	valType reflect2.Type
+}
+
+func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	valType := decoder.valType
+	obj := valType.UnsafeIndirect(ptr)
+	unmarshaler := obj.(json.Unmarshaler)
+	iter.nextToken()
+	iter.unreadByte() // skip spaces
+	bytes := iter.SkipAndReturnBytes()
+	err := unmarshaler.UnmarshalJSON(bytes)
+	if err != nil {
+		iter.ReportError("unmarshalerDecoder", err.Error())
+	}
+}
+
+type textUnmarshalerDecoder struct {
+	valType reflect2.Type
+}
+
+func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	valType := decoder.valType
+	obj := valType.UnsafeIndirect(ptr)
+	if reflect2.IsNil(obj) {
+		ptrType := valType.(*reflect2.UnsafePtrType)
+		elemType := ptrType.Elem()
+		elem := elemType.UnsafeNew()
+		ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem))
+		obj = valType.UnsafeIndirect(ptr)
+	}
+	unmarshaler := (obj).(encoding.TextUnmarshaler)
+	str := iter.ReadString()
+	err := unmarshaler.UnmarshalText([]byte(str))
+	if err != nil {
+		iter.ReportError("textUnmarshalerDecoder", err.Error())
+	}
+}

+ 451 - 0
vendor/github.com/json-iterator/go/reflect_native.go

@@ -0,0 +1,451 @@
+package jsoniter
+
+import (
+	"encoding/base64"
+	"reflect"
+	"strconv"
+	"unsafe"
+
+	"github.com/modern-go/reflect2"
+)
+
+const ptrSize = 32 << uintptr(^uintptr(0)>>63)
+
+func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder {
+	if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
+		sliceDecoder := decoderOfSlice(ctx, typ)
+		return &base64Codec{sliceDecoder: sliceDecoder}
+	}
+	typeName := typ.String()
+	kind := typ.Kind()
+	switch kind {
+	case reflect.String:
+		if typeName != "string" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
+		}
+		return &stringCodec{}
+	case reflect.Int:
+		if typeName != "int" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
+		}
+		if strconv.IntSize == 32 {
+			return &int32Codec{}
+		}
+		return &int64Codec{}
+	case reflect.Int8:
+		if typeName != "int8" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
+		}
+		return &int8Codec{}
+	case reflect.Int16:
+		if typeName != "int16" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
+		}
+		return &int16Codec{}
+	case reflect.Int32:
+		if typeName != "int32" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
+		}
+		return &int32Codec{}
+	case reflect.Int64:
+		if typeName != "int64" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
+		}
+		return &int64Codec{}
+	case reflect.Uint:
+		if typeName != "uint" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
+		}
+		if strconv.IntSize == 32 {
+			return &uint32Codec{}
+		}
+		return &uint64Codec{}
+	case reflect.Uint8:
+		if typeName != "uint8" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
+		}
+		return &uint8Codec{}
+	case reflect.Uint16:
+		if typeName != "uint16" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
+		}
+		return &uint16Codec{}
+	case reflect.Uint32:
+		if typeName != "uint32" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
+		}
+		return &uint32Codec{}
+	case reflect.Uintptr:
+		if typeName != "uintptr" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
+		}
+		if ptrSize == 32 {
+			return &uint32Codec{}
+		}
+		return &uint64Codec{}
+	case reflect.Uint64:
+		if typeName != "uint64" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
+		}
+		return &uint64Codec{}
+	case reflect.Float32:
+		if typeName != "float32" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
+		}
+		return &float32Codec{}
+	case reflect.Float64:
+		if typeName != "float64" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
+		}
+		return &float64Codec{}
+	case reflect.Bool:
+		if typeName != "bool" {
+			return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
+		}
+		return &boolCodec{}
+	}
+	return nil
+}
+
+func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder {
+	if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
+		sliceDecoder := decoderOfSlice(ctx, typ)
+		return &base64Codec{sliceDecoder: sliceDecoder}
+	}
+	typeName := typ.String()
+	switch typ.Kind() {
+	case reflect.String:
+		if typeName != "string" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
+		}
+		return &stringCodec{}
+	case reflect.Int:
+		if typeName != "int" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
+		}
+		if strconv.IntSize == 32 {
+			return &int32Codec{}
+		}
+		return &int64Codec{}
+	case reflect.Int8:
+		if typeName != "int8" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
+		}
+		return &int8Codec{}
+	case reflect.Int16:
+		if typeName != "int16" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
+		}
+		return &int16Codec{}
+	case reflect.Int32:
+		if typeName != "int32" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
+		}
+		return &int32Codec{}
+	case reflect.Int64:
+		if typeName != "int64" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
+		}
+		return &int64Codec{}
+	case reflect.Uint:
+		if typeName != "uint" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
+		}
+		if strconv.IntSize == 32 {
+			return &uint32Codec{}
+		}
+		return &uint64Codec{}
+	case reflect.Uint8:
+		if typeName != "uint8" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
+		}
+		return &uint8Codec{}
+	case reflect.Uint16:
+		if typeName != "uint16" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
+		}
+		return &uint16Codec{}
+	case reflect.Uint32:
+		if typeName != "uint32" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
+		}
+		return &uint32Codec{}
+	case reflect.Uintptr:
+		if typeName != "uintptr" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
+		}
+		if ptrSize == 32 {
+			return &uint32Codec{}
+		}
+		return &uint64Codec{}
+	case reflect.Uint64:
+		if typeName != "uint64" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
+		}
+		return &uint64Codec{}
+	case reflect.Float32:
+		if typeName != "float32" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
+		}
+		return &float32Codec{}
+	case reflect.Float64:
+		if typeName != "float64" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
+		}
+		return &float64Codec{}
+	case reflect.Bool:
+		if typeName != "bool" {
+			return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
+		}
+		return &boolCodec{}
+	}
+	return nil
+}
+
+type stringCodec struct {
+}
+
+func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*string)(ptr)) = iter.ReadString()
+}
+
+func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	str := *((*string)(ptr))
+	stream.WriteString(str)
+}
+
+func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*string)(ptr)) == ""
+}
+
+type int8Codec struct {
+}
+
+func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*int8)(ptr)) = iter.ReadInt8()
+	}
+}
+
+func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteInt8(*((*int8)(ptr)))
+}
+
+func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*int8)(ptr)) == 0
+}
+
+type int16Codec struct {
+}
+
+func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*int16)(ptr)) = iter.ReadInt16()
+	}
+}
+
+func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteInt16(*((*int16)(ptr)))
+}
+
+func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*int16)(ptr)) == 0
+}
+
+type int32Codec struct {
+}
+
+func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*int32)(ptr)) = iter.ReadInt32()
+	}
+}
+
+func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteInt32(*((*int32)(ptr)))
+}
+
+func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*int32)(ptr)) == 0
+}
+
+type int64Codec struct {
+}
+
+func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*int64)(ptr)) = iter.ReadInt64()
+	}
+}
+
+func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteInt64(*((*int64)(ptr)))
+}
+
+func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*int64)(ptr)) == 0
+}
+
+type uint8Codec struct {
+}
+
+func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*uint8)(ptr)) = iter.ReadUint8()
+	}
+}
+
+func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteUint8(*((*uint8)(ptr)))
+}
+
+func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*uint8)(ptr)) == 0
+}
+
+type uint16Codec struct {
+}
+
+func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*uint16)(ptr)) = iter.ReadUint16()
+	}
+}
+
+func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteUint16(*((*uint16)(ptr)))
+}
+
+func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*uint16)(ptr)) == 0
+}
+
+type uint32Codec struct {
+}
+
+func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*uint32)(ptr)) = iter.ReadUint32()
+	}
+}
+
+func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteUint32(*((*uint32)(ptr)))
+}
+
+func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*uint32)(ptr)) == 0
+}
+
+type uint64Codec struct {
+}
+
+func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*uint64)(ptr)) = iter.ReadUint64()
+	}
+}
+
+func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteUint64(*((*uint64)(ptr)))
+}
+
+func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*uint64)(ptr)) == 0
+}
+
+type float32Codec struct {
+}
+
+func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*float32)(ptr)) = iter.ReadFloat32()
+	}
+}
+
+func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteFloat32(*((*float32)(ptr)))
+}
+
+func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*float32)(ptr)) == 0
+}
+
+type float64Codec struct {
+}
+
+func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*float64)(ptr)) = iter.ReadFloat64()
+	}
+}
+
+func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteFloat64(*((*float64)(ptr)))
+}
+
+func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*float64)(ptr)) == 0
+}
+
+type boolCodec struct {
+}
+
+func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.ReadNil() {
+		*((*bool)(ptr)) = iter.ReadBool()
+	}
+}
+
+func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteBool(*((*bool)(ptr)))
+}
+
+func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return !(*((*bool)(ptr)))
+}
+
+type base64Codec struct {
+	sliceType    *reflect2.UnsafeSliceType
+	sliceDecoder ValDecoder
+}
+
+func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if iter.ReadNil() {
+		codec.sliceType.UnsafeSetNil(ptr)
+		return
+	}
+	switch iter.WhatIsNext() {
+	case StringValue:
+		src := iter.ReadString()
+		dst, err := base64.StdEncoding.DecodeString(src)
+		if err != nil {
+			iter.ReportError("decode base64", err.Error())
+		} else {
+			codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst))
+		}
+	case ArrayValue:
+		codec.sliceDecoder.Decode(ptr, iter)
+	default:
+		iter.ReportError("base64Codec", "invalid input")
+	}
+}
+
+func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	src := *((*[]byte)(ptr))
+	if len(src) == 0 {
+		stream.WriteNil()
+		return
+	}
+	encoding := base64.StdEncoding
+	stream.writeByte('"')
+	size := encoding.EncodedLen(len(src))
+	buf := make([]byte, size)
+	encoding.Encode(buf, src)
+	stream.buf = append(stream.buf, buf...)
+	stream.writeByte('"')
+}
+
+func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*[]byte)(ptr))) == 0
+}

+ 133 - 0
vendor/github.com/json-iterator/go/reflect_optional.go

@@ -0,0 +1,133 @@
+package jsoniter
+
+import (
+	"github.com/modern-go/reflect2"
+	"reflect"
+	"unsafe"
+)
+
+func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder {
+	ptrType := typ.(*reflect2.UnsafePtrType)
+	elemType := ptrType.Elem()
+	decoder := decoderOfType(ctx, elemType)
+	if ctx.prefix == "" && elemType.Kind() == reflect.Ptr {
+		return &dereferenceDecoder{elemType, decoder}
+	}
+	return &OptionalDecoder{elemType, decoder}
+}
+
+func encoderOfOptional(ctx *ctx, typ reflect2.Type) ValEncoder {
+	ptrType := typ.(*reflect2.UnsafePtrType)
+	elemType := ptrType.Elem()
+	elemEncoder := encoderOfType(ctx, elemType)
+	encoder := &OptionalEncoder{elemEncoder}
+	return encoder
+}
+
+type OptionalDecoder struct {
+	ValueType    reflect2.Type
+	ValueDecoder ValDecoder
+}
+
+func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if iter.ReadNil() {
+		*((*unsafe.Pointer)(ptr)) = nil
+	} else {
+		if *((*unsafe.Pointer)(ptr)) == nil {
+			//pointer to null, we have to allocate memory to hold the value
+			newPtr := decoder.ValueType.UnsafeNew()
+			decoder.ValueDecoder.Decode(newPtr, iter)
+			*((*unsafe.Pointer)(ptr)) = newPtr
+		} else {
+			//reuse existing instance
+			decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
+		}
+	}
+}
+
+type dereferenceDecoder struct {
+	// only to deference a pointer
+	valueType    reflect2.Type
+	valueDecoder ValDecoder
+}
+
+func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if *((*unsafe.Pointer)(ptr)) == nil {
+		//pointer to null, we have to allocate memory to hold the value
+		newPtr := decoder.valueType.UnsafeNew()
+		decoder.valueDecoder.Decode(newPtr, iter)
+		*((*unsafe.Pointer)(ptr)) = newPtr
+	} else {
+		//reuse existing instance
+		decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
+	}
+}
+
+type OptionalEncoder struct {
+	ValueEncoder ValEncoder
+}
+
+func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	if *((*unsafe.Pointer)(ptr)) == nil {
+		stream.WriteNil()
+	} else {
+		encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
+	}
+}
+
+func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return *((*unsafe.Pointer)(ptr)) == nil
+}
+
+type dereferenceEncoder struct {
+	ValueEncoder ValEncoder
+}
+
+func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	if *((*unsafe.Pointer)(ptr)) == nil {
+		stream.WriteNil()
+	} else {
+		encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
+	}
+}
+
+func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	dePtr := *((*unsafe.Pointer)(ptr))
+	if dePtr == nil {
+		return true
+	}
+	return encoder.ValueEncoder.IsEmpty(dePtr)
+}
+
+func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
+	deReferenced := *((*unsafe.Pointer)(ptr))
+	if deReferenced == nil {
+		return true
+	}
+	isEmbeddedPtrNil, converted := encoder.ValueEncoder.(IsEmbeddedPtrNil)
+	if !converted {
+		return false
+	}
+	fieldPtr := unsafe.Pointer(deReferenced)
+	return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
+}
+
+type referenceEncoder struct {
+	encoder ValEncoder
+}
+
+func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	encoder.encoder.Encode(unsafe.Pointer(&ptr), stream)
+}
+
+func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr))
+}
+
+type referenceDecoder struct {
+	decoder ValDecoder
+}
+
+func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.decoder.Decode(unsafe.Pointer(&ptr), iter)
+}

+ 99 - 0
vendor/github.com/json-iterator/go/reflect_slice.go

@@ -0,0 +1,99 @@
+package jsoniter
+
+import (
+	"fmt"
+	"github.com/modern-go/reflect2"
+	"io"
+	"unsafe"
+)
+
+func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder {
+	sliceType := typ.(*reflect2.UnsafeSliceType)
+	decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
+	return &sliceDecoder{sliceType, decoder}
+}
+
+func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder {
+	sliceType := typ.(*reflect2.UnsafeSliceType)
+	encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
+	return &sliceEncoder{sliceType, encoder}
+}
+
+type sliceEncoder struct {
+	sliceType   *reflect2.UnsafeSliceType
+	elemEncoder ValEncoder
+}
+
+func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	if encoder.sliceType.UnsafeIsNil(ptr) {
+		stream.WriteNil()
+		return
+	}
+	length := encoder.sliceType.UnsafeLengthOf(ptr)
+	if length == 0 {
+		stream.WriteEmptyArray()
+		return
+	}
+	stream.WriteArrayStart()
+	encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream)
+	for i := 1; i < length; i++ {
+		stream.WriteMore()
+		elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i)
+		encoder.elemEncoder.Encode(elemPtr, stream)
+	}
+	stream.WriteArrayEnd()
+	if stream.Error != nil && stream.Error != io.EOF {
+		stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error())
+	}
+}
+
+func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.sliceType.UnsafeLengthOf(ptr) == 0
+}
+
+type sliceDecoder struct {
+	sliceType   *reflect2.UnsafeSliceType
+	elemDecoder ValDecoder
+}
+
+func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.doDecode(ptr, iter)
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
+	}
+}
+
+func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
+	c := iter.nextToken()
+	sliceType := decoder.sliceType
+	if c == 'n' {
+		iter.skipThreeBytes('u', 'l', 'l')
+		sliceType.UnsafeSetNil(ptr)
+		return
+	}
+	if c != '[' {
+		iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c}))
+		return
+	}
+	c = iter.nextToken()
+	if c == ']' {
+		sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0))
+		return
+	}
+	iter.unreadByte()
+	sliceType.UnsafeGrow(ptr, 1)
+	elemPtr := sliceType.UnsafeGetIndex(ptr, 0)
+	decoder.elemDecoder.Decode(elemPtr, iter)
+	length := 1
+	for c = iter.nextToken(); c == ','; c = iter.nextToken() {
+		idx := length
+		length += 1
+		sliceType.UnsafeGrow(ptr, length)
+		elemPtr = sliceType.UnsafeGetIndex(ptr, idx)
+		decoder.elemDecoder.Decode(elemPtr, iter)
+	}
+	if c != ']' {
+		iter.ReportError("decode slice", "expect ], but found "+string([]byte{c}))
+		return
+	}
+}

+ 1048 - 0
vendor/github.com/json-iterator/go/reflect_struct_decoder.go

@@ -0,0 +1,1048 @@
+package jsoniter
+
+import (
+	"fmt"
+	"io"
+	"strings"
+	"unsafe"
+
+	"github.com/modern-go/reflect2"
+)
+
+func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
+	bindings := map[string]*Binding{}
+	structDescriptor := describeStruct(ctx, typ)
+	for _, binding := range structDescriptor.Fields {
+		for _, fromName := range binding.FromNames {
+			old := bindings[fromName]
+			if old == nil {
+				bindings[fromName] = binding
+				continue
+			}
+			ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding)
+			if ignoreOld {
+				delete(bindings, fromName)
+			}
+			if !ignoreNew {
+				bindings[fromName] = binding
+			}
+		}
+	}
+	fields := map[string]*structFieldDecoder{}
+	for k, binding := range bindings {
+		fields[k] = binding.Decoder.(*structFieldDecoder)
+	}
+
+	if !ctx.caseSensitive() {
+		for k, binding := range bindings {
+			if _, found := fields[strings.ToLower(k)]; !found {
+				fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
+			}
+		}
+	}
+
+	return createStructDecoder(ctx, typ, fields)
+}
+
+func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder {
+	if ctx.disallowUnknownFields {
+		return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true}
+	}
+	knownHash := map[int64]struct{}{
+		0: {},
+	}
+
+	switch len(fields) {
+	case 0:
+		return &skipObjectDecoder{typ}
+	case 1:
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}
+		}
+	case 2:
+		var fieldHash1 int64
+		var fieldHash2 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldHash1 == 0 {
+				fieldHash1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else {
+				fieldHash2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			}
+		}
+		return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}
+	case 3:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			}
+		}
+		return &threeFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3}
+	case 4:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			}
+		}
+		return &fourFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4}
+	case 5:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldName5 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			}
+		}
+		return &fiveFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5}
+	case 6:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldName5 int64
+		var fieldName6 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		var fieldDecoder6 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else if fieldName5 == 0 {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			} else {
+				fieldName6 = fieldHash
+				fieldDecoder6 = fieldDecoder
+			}
+		}
+		return &sixFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5,
+			fieldName6, fieldDecoder6}
+	case 7:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldName5 int64
+		var fieldName6 int64
+		var fieldName7 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		var fieldDecoder6 *structFieldDecoder
+		var fieldDecoder7 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else if fieldName5 == 0 {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			} else if fieldName6 == 0 {
+				fieldName6 = fieldHash
+				fieldDecoder6 = fieldDecoder
+			} else {
+				fieldName7 = fieldHash
+				fieldDecoder7 = fieldDecoder
+			}
+		}
+		return &sevenFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5,
+			fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7}
+	case 8:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldName5 int64
+		var fieldName6 int64
+		var fieldName7 int64
+		var fieldName8 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		var fieldDecoder6 *structFieldDecoder
+		var fieldDecoder7 *structFieldDecoder
+		var fieldDecoder8 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else if fieldName5 == 0 {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			} else if fieldName6 == 0 {
+				fieldName6 = fieldHash
+				fieldDecoder6 = fieldDecoder
+			} else if fieldName7 == 0 {
+				fieldName7 = fieldHash
+				fieldDecoder7 = fieldDecoder
+			} else {
+				fieldName8 = fieldHash
+				fieldDecoder8 = fieldDecoder
+			}
+		}
+		return &eightFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5,
+			fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7,
+			fieldName8, fieldDecoder8}
+	case 9:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldName5 int64
+		var fieldName6 int64
+		var fieldName7 int64
+		var fieldName8 int64
+		var fieldName9 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		var fieldDecoder6 *structFieldDecoder
+		var fieldDecoder7 *structFieldDecoder
+		var fieldDecoder8 *structFieldDecoder
+		var fieldDecoder9 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else if fieldName5 == 0 {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			} else if fieldName6 == 0 {
+				fieldName6 = fieldHash
+				fieldDecoder6 = fieldDecoder
+			} else if fieldName7 == 0 {
+				fieldName7 = fieldHash
+				fieldDecoder7 = fieldDecoder
+			} else if fieldName8 == 0 {
+				fieldName8 = fieldHash
+				fieldDecoder8 = fieldDecoder
+			} else {
+				fieldName9 = fieldHash
+				fieldDecoder9 = fieldDecoder
+			}
+		}
+		return &nineFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5,
+			fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7,
+			fieldName8, fieldDecoder8,
+			fieldName9, fieldDecoder9}
+	case 10:
+		var fieldName1 int64
+		var fieldName2 int64
+		var fieldName3 int64
+		var fieldName4 int64
+		var fieldName5 int64
+		var fieldName6 int64
+		var fieldName7 int64
+		var fieldName8 int64
+		var fieldName9 int64
+		var fieldName10 int64
+		var fieldDecoder1 *structFieldDecoder
+		var fieldDecoder2 *structFieldDecoder
+		var fieldDecoder3 *structFieldDecoder
+		var fieldDecoder4 *structFieldDecoder
+		var fieldDecoder5 *structFieldDecoder
+		var fieldDecoder6 *structFieldDecoder
+		var fieldDecoder7 *structFieldDecoder
+		var fieldDecoder8 *structFieldDecoder
+		var fieldDecoder9 *structFieldDecoder
+		var fieldDecoder10 *structFieldDecoder
+		for fieldName, fieldDecoder := range fields {
+			fieldHash := calcHash(fieldName, ctx.caseSensitive())
+			_, known := knownHash[fieldHash]
+			if known {
+				return &generalStructDecoder{typ, fields, false}
+			}
+			knownHash[fieldHash] = struct{}{}
+			if fieldName1 == 0 {
+				fieldName1 = fieldHash
+				fieldDecoder1 = fieldDecoder
+			} else if fieldName2 == 0 {
+				fieldName2 = fieldHash
+				fieldDecoder2 = fieldDecoder
+			} else if fieldName3 == 0 {
+				fieldName3 = fieldHash
+				fieldDecoder3 = fieldDecoder
+			} else if fieldName4 == 0 {
+				fieldName4 = fieldHash
+				fieldDecoder4 = fieldDecoder
+			} else if fieldName5 == 0 {
+				fieldName5 = fieldHash
+				fieldDecoder5 = fieldDecoder
+			} else if fieldName6 == 0 {
+				fieldName6 = fieldHash
+				fieldDecoder6 = fieldDecoder
+			} else if fieldName7 == 0 {
+				fieldName7 = fieldHash
+				fieldDecoder7 = fieldDecoder
+			} else if fieldName8 == 0 {
+				fieldName8 = fieldHash
+				fieldDecoder8 = fieldDecoder
+			} else if fieldName9 == 0 {
+				fieldName9 = fieldHash
+				fieldDecoder9 = fieldDecoder
+			} else {
+				fieldName10 = fieldHash
+				fieldDecoder10 = fieldDecoder
+			}
+		}
+		return &tenFieldsStructDecoder{typ,
+			fieldName1, fieldDecoder1,
+			fieldName2, fieldDecoder2,
+			fieldName3, fieldDecoder3,
+			fieldName4, fieldDecoder4,
+			fieldName5, fieldDecoder5,
+			fieldName6, fieldDecoder6,
+			fieldName7, fieldDecoder7,
+			fieldName8, fieldDecoder8,
+			fieldName9, fieldDecoder9,
+			fieldName10, fieldDecoder10}
+	}
+	return &generalStructDecoder{typ, fields, false}
+}
+
+type generalStructDecoder struct {
+	typ                   reflect2.Type
+	fields                map[string]*structFieldDecoder
+	disallowUnknownFields bool
+}
+
+func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	var c byte
+	for c = ','; c == ','; c = iter.nextToken() {
+		decoder.decodeOneField(ptr, iter)
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+	if c != '}' {
+		iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c}))
+	}
+}
+
+func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) {
+	var field string
+	var fieldDecoder *structFieldDecoder
+	if iter.cfg.objectFieldMustBeSimpleString {
+		fieldBytes := iter.ReadStringAsSlice()
+		field = *(*string)(unsafe.Pointer(&fieldBytes))
+		fieldDecoder = decoder.fields[field]
+		if fieldDecoder == nil && !iter.cfg.caseSensitive {
+			fieldDecoder = decoder.fields[strings.ToLower(field)]
+		}
+	} else {
+		field = iter.ReadString()
+		fieldDecoder = decoder.fields[field]
+		if fieldDecoder == nil && !iter.cfg.caseSensitive {
+			fieldDecoder = decoder.fields[strings.ToLower(field)]
+		}
+	}
+	if fieldDecoder == nil {
+		msg := "found unknown field: " + field
+		if decoder.disallowUnknownFields {
+			iter.ReportError("ReadObject", msg)
+		}
+		c := iter.nextToken()
+		if c != ':' {
+			iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
+		}
+		iter.Skip()
+		return
+	}
+	c := iter.nextToken()
+	if c != ':' {
+		iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
+	}
+	fieldDecoder.Decode(ptr, iter)
+}
+
+type skipObjectDecoder struct {
+	typ reflect2.Type
+}
+
+func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	valueType := iter.WhatIsNext()
+	if valueType != ObjectValue && valueType != NilValue {
+		iter.ReportError("skipObjectDecoder", "expect object or null")
+		return
+	}
+	iter.Skip()
+}
+
+type oneFieldStructDecoder struct {
+	typ          reflect2.Type
+	fieldHash    int64
+	fieldDecoder *structFieldDecoder
+}
+
+func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		if iter.readFieldHash() == decoder.fieldHash {
+			decoder.fieldDecoder.Decode(ptr, iter)
+		} else {
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type twoFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+}
+
+func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type threeFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+}
+
+func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type fourFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+}
+
+func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type fiveFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+	fieldHash5    int64
+	fieldDecoder5 *structFieldDecoder
+}
+
+func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type sixFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+	fieldHash5    int64
+	fieldDecoder5 *structFieldDecoder
+	fieldHash6    int64
+	fieldDecoder6 *structFieldDecoder
+}
+
+func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		case decoder.fieldHash6:
+			decoder.fieldDecoder6.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type sevenFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+	fieldHash5    int64
+	fieldDecoder5 *structFieldDecoder
+	fieldHash6    int64
+	fieldDecoder6 *structFieldDecoder
+	fieldHash7    int64
+	fieldDecoder7 *structFieldDecoder
+}
+
+func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		case decoder.fieldHash6:
+			decoder.fieldDecoder6.Decode(ptr, iter)
+		case decoder.fieldHash7:
+			decoder.fieldDecoder7.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type eightFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+	fieldHash5    int64
+	fieldDecoder5 *structFieldDecoder
+	fieldHash6    int64
+	fieldDecoder6 *structFieldDecoder
+	fieldHash7    int64
+	fieldDecoder7 *structFieldDecoder
+	fieldHash8    int64
+	fieldDecoder8 *structFieldDecoder
+}
+
+func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		case decoder.fieldHash6:
+			decoder.fieldDecoder6.Decode(ptr, iter)
+		case decoder.fieldHash7:
+			decoder.fieldDecoder7.Decode(ptr, iter)
+		case decoder.fieldHash8:
+			decoder.fieldDecoder8.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type nineFieldsStructDecoder struct {
+	typ           reflect2.Type
+	fieldHash1    int64
+	fieldDecoder1 *structFieldDecoder
+	fieldHash2    int64
+	fieldDecoder2 *structFieldDecoder
+	fieldHash3    int64
+	fieldDecoder3 *structFieldDecoder
+	fieldHash4    int64
+	fieldDecoder4 *structFieldDecoder
+	fieldHash5    int64
+	fieldDecoder5 *structFieldDecoder
+	fieldHash6    int64
+	fieldDecoder6 *structFieldDecoder
+	fieldHash7    int64
+	fieldDecoder7 *structFieldDecoder
+	fieldHash8    int64
+	fieldDecoder8 *structFieldDecoder
+	fieldHash9    int64
+	fieldDecoder9 *structFieldDecoder
+}
+
+func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		case decoder.fieldHash6:
+			decoder.fieldDecoder6.Decode(ptr, iter)
+		case decoder.fieldHash7:
+			decoder.fieldDecoder7.Decode(ptr, iter)
+		case decoder.fieldHash8:
+			decoder.fieldDecoder8.Decode(ptr, iter)
+		case decoder.fieldHash9:
+			decoder.fieldDecoder9.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type tenFieldsStructDecoder struct {
+	typ            reflect2.Type
+	fieldHash1     int64
+	fieldDecoder1  *structFieldDecoder
+	fieldHash2     int64
+	fieldDecoder2  *structFieldDecoder
+	fieldHash3     int64
+	fieldDecoder3  *structFieldDecoder
+	fieldHash4     int64
+	fieldDecoder4  *structFieldDecoder
+	fieldHash5     int64
+	fieldDecoder5  *structFieldDecoder
+	fieldHash6     int64
+	fieldDecoder6  *structFieldDecoder
+	fieldHash7     int64
+	fieldDecoder7  *structFieldDecoder
+	fieldHash8     int64
+	fieldDecoder8  *structFieldDecoder
+	fieldHash9     int64
+	fieldDecoder9  *structFieldDecoder
+	fieldHash10    int64
+	fieldDecoder10 *structFieldDecoder
+}
+
+func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	if !iter.readObjectStart() {
+		return
+	}
+	for {
+		switch iter.readFieldHash() {
+		case decoder.fieldHash1:
+			decoder.fieldDecoder1.Decode(ptr, iter)
+		case decoder.fieldHash2:
+			decoder.fieldDecoder2.Decode(ptr, iter)
+		case decoder.fieldHash3:
+			decoder.fieldDecoder3.Decode(ptr, iter)
+		case decoder.fieldHash4:
+			decoder.fieldDecoder4.Decode(ptr, iter)
+		case decoder.fieldHash5:
+			decoder.fieldDecoder5.Decode(ptr, iter)
+		case decoder.fieldHash6:
+			decoder.fieldDecoder6.Decode(ptr, iter)
+		case decoder.fieldHash7:
+			decoder.fieldDecoder7.Decode(ptr, iter)
+		case decoder.fieldHash8:
+			decoder.fieldDecoder8.Decode(ptr, iter)
+		case decoder.fieldHash9:
+			decoder.fieldDecoder9.Decode(ptr, iter)
+		case decoder.fieldHash10:
+			decoder.fieldDecoder10.Decode(ptr, iter)
+		default:
+			iter.Skip()
+		}
+		if iter.isObjectEnd() {
+			break
+		}
+	}
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
+	}
+}
+
+type structFieldDecoder struct {
+	field        reflect2.StructField
+	fieldDecoder ValDecoder
+}
+
+func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	fieldPtr := decoder.field.UnsafeGet(ptr)
+	decoder.fieldDecoder.Decode(fieldPtr, iter)
+	if iter.Error != nil && iter.Error != io.EOF {
+		iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error())
+	}
+}
+
+type stringModeStringDecoder struct {
+	elemDecoder ValDecoder
+	cfg         *frozenConfig
+}
+
+func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.elemDecoder.Decode(ptr, iter)
+	str := *((*string)(ptr))
+	tempIter := decoder.cfg.BorrowIterator([]byte(str))
+	defer decoder.cfg.ReturnIterator(tempIter)
+	*((*string)(ptr)) = tempIter.ReadString()
+}
+
+type stringModeNumberDecoder struct {
+	elemDecoder ValDecoder
+}
+
+func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	c := iter.nextToken()
+	if c != '"' {
+		iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
+		return
+	}
+	decoder.elemDecoder.Decode(ptr, iter)
+	if iter.Error != nil {
+		return
+	}
+	c = iter.readByte()
+	if c != '"' {
+		iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
+		return
+	}
+}

+ 210 - 0
vendor/github.com/json-iterator/go/reflect_struct_encoder.go

@@ -0,0 +1,210 @@
+package jsoniter
+
+import (
+	"fmt"
+	"github.com/modern-go/reflect2"
+	"io"
+	"reflect"
+	"unsafe"
+)
+
+func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
+	type bindingTo struct {
+		binding *Binding
+		toName  string
+		ignored bool
+	}
+	orderedBindings := []*bindingTo{}
+	structDescriptor := describeStruct(ctx, typ)
+	for _, binding := range structDescriptor.Fields {
+		for _, toName := range binding.ToNames {
+			new := &bindingTo{
+				binding: binding,
+				toName:  toName,
+			}
+			for _, old := range orderedBindings {
+				if old.toName != toName {
+					continue
+				}
+				old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding)
+			}
+			orderedBindings = append(orderedBindings, new)
+		}
+	}
+	if len(orderedBindings) == 0 {
+		return &emptyStructEncoder{}
+	}
+	finalOrderedFields := []structFieldTo{}
+	for _, bindingTo := range orderedBindings {
+		if !bindingTo.ignored {
+			finalOrderedFields = append(finalOrderedFields, structFieldTo{
+				encoder: bindingTo.binding.Encoder.(*structFieldEncoder),
+				toName:  bindingTo.toName,
+			})
+		}
+	}
+	return &structEncoder{typ, finalOrderedFields}
+}
+
+func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty {
+	encoder := createEncoderOfNative(ctx, typ)
+	if encoder != nil {
+		return encoder
+	}
+	kind := typ.Kind()
+	switch kind {
+	case reflect.Interface:
+		return &dynamicEncoder{typ}
+	case reflect.Struct:
+		return &structEncoder{typ: typ}
+	case reflect.Array:
+		return &arrayEncoder{}
+	case reflect.Slice:
+		return &sliceEncoder{}
+	case reflect.Map:
+		return encoderOfMap(ctx, typ)
+	case reflect.Ptr:
+		return &OptionalEncoder{}
+	default:
+		return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)}
+	}
+}
+
+func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
+	newTagged := new.Field.Tag().Get(cfg.getTagKey()) != ""
+	oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != ""
+	if newTagged {
+		if oldTagged {
+			if len(old.levels) > len(new.levels) {
+				return true, false
+			} else if len(new.levels) > len(old.levels) {
+				return false, true
+			} else {
+				return true, true
+			}
+		} else {
+			return true, false
+		}
+	} else {
+		if oldTagged {
+			return true, false
+		}
+		if len(old.levels) > len(new.levels) {
+			return true, false
+		} else if len(new.levels) > len(old.levels) {
+			return false, true
+		} else {
+			return true, true
+		}
+	}
+}
+
+type structFieldEncoder struct {
+	field        reflect2.StructField
+	fieldEncoder ValEncoder
+	omitempty    bool
+}
+
+func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	fieldPtr := encoder.field.UnsafeGet(ptr)
+	encoder.fieldEncoder.Encode(fieldPtr, stream)
+	if stream.Error != nil && stream.Error != io.EOF {
+		stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error())
+	}
+}
+
+func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	fieldPtr := encoder.field.UnsafeGet(ptr)
+	return encoder.fieldEncoder.IsEmpty(fieldPtr)
+}
+
+func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
+	isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil)
+	if !converted {
+		return false
+	}
+	fieldPtr := encoder.field.UnsafeGet(ptr)
+	return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
+}
+
+type IsEmbeddedPtrNil interface {
+	IsEmbeddedPtrNil(ptr unsafe.Pointer) bool
+}
+
+type structEncoder struct {
+	typ    reflect2.Type
+	fields []structFieldTo
+}
+
+type structFieldTo struct {
+	encoder *structFieldEncoder
+	toName  string
+}
+
+func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteObjectStart()
+	isNotFirst := false
+	for _, field := range encoder.fields {
+		if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
+			continue
+		}
+		if field.encoder.IsEmbeddedPtrNil(ptr) {
+			continue
+		}
+		if isNotFirst {
+			stream.WriteMore()
+		}
+		stream.WriteObjectField(field.toName)
+		field.encoder.Encode(ptr, stream)
+		isNotFirst = true
+	}
+	stream.WriteObjectEnd()
+	if stream.Error != nil && stream.Error != io.EOF {
+		stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error())
+	}
+}
+
+func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return false
+}
+
+type emptyStructEncoder struct {
+}
+
+func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteEmptyObject()
+}
+
+func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return false
+}
+
+type stringModeNumberEncoder struct {
+	elemEncoder ValEncoder
+}
+
+func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.writeByte('"')
+	encoder.elemEncoder.Encode(ptr, stream)
+	stream.writeByte('"')
+}
+
+func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.elemEncoder.IsEmpty(ptr)
+}
+
+type stringModeStringEncoder struct {
+	elemEncoder ValEncoder
+	cfg         *frozenConfig
+}
+
+func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	tempStream := encoder.cfg.BorrowStream(nil)
+	defer encoder.cfg.ReturnStream(tempStream)
+	encoder.elemEncoder.Encode(ptr, tempStream)
+	stream.WriteString(string(tempStream.Buffer()))
+}
+
+func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.elemEncoder.IsEmpty(ptr)
+}

+ 211 - 0
vendor/github.com/json-iterator/go/stream.go

@@ -0,0 +1,211 @@
+package jsoniter
+
+import (
+	"io"
+)
+
+// stream is a io.Writer like object, with JSON specific write functions.
+// Error is not returned as return value, but stored as Error member on this stream instance.
+type Stream struct {
+	cfg        *frozenConfig
+	out        io.Writer
+	buf        []byte
+	Error      error
+	indention  int
+	Attachment interface{} // open for customized encoder
+}
+
+// NewStream create new stream instance.
+// cfg can be jsoniter.ConfigDefault.
+// out can be nil if write to internal buffer.
+// bufSize is the initial size for the internal buffer in bytes.
+func NewStream(cfg API, out io.Writer, bufSize int) *Stream {
+	return &Stream{
+		cfg:       cfg.(*frozenConfig),
+		out:       out,
+		buf:       make([]byte, 0, bufSize),
+		Error:     nil,
+		indention: 0,
+	}
+}
+
+// Pool returns a pool can provide more stream with same configuration
+func (stream *Stream) Pool() StreamPool {
+	return stream.cfg
+}
+
+// Reset reuse this stream instance by assign a new writer
+func (stream *Stream) Reset(out io.Writer) {
+	stream.out = out
+	stream.buf = stream.buf[:0]
+}
+
+// Available returns how many bytes are unused in the buffer.
+func (stream *Stream) Available() int {
+	return cap(stream.buf) - len(stream.buf)
+}
+
+// Buffered returns the number of bytes that have been written into the current buffer.
+func (stream *Stream) Buffered() int {
+	return len(stream.buf)
+}
+
+// Buffer if writer is nil, use this method to take the result
+func (stream *Stream) Buffer() []byte {
+	return stream.buf
+}
+
+// SetBuffer allows to append to the internal buffer directly
+func (stream *Stream) SetBuffer(buf []byte) {
+	stream.buf = buf
+}
+
+// Write writes the contents of p into the buffer.
+// It returns the number of bytes written.
+// If nn < len(p), it also returns an error explaining
+// why the write is short.
+func (stream *Stream) Write(p []byte) (nn int, err error) {
+	stream.buf = append(stream.buf, p...)
+	if stream.out != nil {
+		nn, err = stream.out.Write(stream.buf)
+		stream.buf = stream.buf[nn:]
+		return
+	}
+	return len(p), nil
+}
+
+// WriteByte writes a single byte.
+func (stream *Stream) writeByte(c byte) {
+	stream.buf = append(stream.buf, c)
+}
+
+func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) {
+	stream.buf = append(stream.buf, c1, c2)
+}
+
+func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
+	stream.buf = append(stream.buf, c1, c2, c3)
+}
+
+func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
+	stream.buf = append(stream.buf, c1, c2, c3, c4)
+}
+
+func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
+	stream.buf = append(stream.buf, c1, c2, c3, c4, c5)
+}
+
+// Flush writes any buffered data to the underlying io.Writer.
+func (stream *Stream) Flush() error {
+	if stream.out == nil {
+		return nil
+	}
+	if stream.Error != nil {
+		return stream.Error
+	}
+	n, err := stream.out.Write(stream.buf)
+	if err != nil {
+		if stream.Error == nil {
+			stream.Error = err
+		}
+		return err
+	}
+	stream.buf = stream.buf[n:]
+	return nil
+}
+
+// WriteRaw write string out without quotes, just like []byte
+func (stream *Stream) WriteRaw(s string) {
+	stream.buf = append(stream.buf, s...)
+}
+
+// WriteNil write null to stream
+func (stream *Stream) WriteNil() {
+	stream.writeFourBytes('n', 'u', 'l', 'l')
+}
+
+// WriteTrue write true to stream
+func (stream *Stream) WriteTrue() {
+	stream.writeFourBytes('t', 'r', 'u', 'e')
+}
+
+// WriteFalse write false to stream
+func (stream *Stream) WriteFalse() {
+	stream.writeFiveBytes('f', 'a', 'l', 's', 'e')
+}
+
+// WriteBool write true or false into stream
+func (stream *Stream) WriteBool(val bool) {
+	if val {
+		stream.WriteTrue()
+	} else {
+		stream.WriteFalse()
+	}
+}
+
+// WriteObjectStart write { with possible indention
+func (stream *Stream) WriteObjectStart() {
+	stream.indention += stream.cfg.indentionStep
+	stream.writeByte('{')
+	stream.writeIndention(0)
+}
+
+// WriteObjectField write "field": with possible indention
+func (stream *Stream) WriteObjectField(field string) {
+	stream.WriteString(field)
+	if stream.indention > 0 {
+		stream.writeTwoBytes(':', ' ')
+	} else {
+		stream.writeByte(':')
+	}
+}
+
+// WriteObjectEnd write } with possible indention
+func (stream *Stream) WriteObjectEnd() {
+	stream.writeIndention(stream.cfg.indentionStep)
+	stream.indention -= stream.cfg.indentionStep
+	stream.writeByte('}')
+}
+
+// WriteEmptyObject write {}
+func (stream *Stream) WriteEmptyObject() {
+	stream.writeByte('{')
+	stream.writeByte('}')
+}
+
+// WriteMore write , with possible indention
+func (stream *Stream) WriteMore() {
+	stream.writeByte(',')
+	stream.writeIndention(0)
+	stream.Flush()
+}
+
+// WriteArrayStart write [ with possible indention
+func (stream *Stream) WriteArrayStart() {
+	stream.indention += stream.cfg.indentionStep
+	stream.writeByte('[')
+	stream.writeIndention(0)
+}
+
+// WriteEmptyArray write []
+func (stream *Stream) WriteEmptyArray() {
+	stream.writeTwoBytes('[', ']')
+}
+
+// WriteArrayEnd write ] with possible indention
+func (stream *Stream) WriteArrayEnd() {
+	stream.writeIndention(stream.cfg.indentionStep)
+	stream.indention -= stream.cfg.indentionStep
+	stream.writeByte(']')
+}
+
+func (stream *Stream) writeIndention(delta int) {
+	if stream.indention == 0 {
+		return
+	}
+	stream.writeByte('\n')
+	toWrite := stream.indention - delta
+	for i := 0; i < toWrite; i++ {
+		stream.buf = append(stream.buf, ' ')
+	}
+}

+ 94 - 0
vendor/github.com/json-iterator/go/stream_float.go

@@ -0,0 +1,94 @@
+package jsoniter
+
+import (
+	"math"
+	"strconv"
+)
+
+var pow10 []uint64
+
+func init() {
+	pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000}
+}
+
+// WriteFloat32 write float32 to stream
+func (stream *Stream) WriteFloat32(val float32) {
+	abs := math.Abs(float64(val))
+	fmt := byte('f')
+	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
+	if abs != 0 {
+		if float32(abs) < 1e-6 || float32(abs) >= 1e21 {
+			fmt = 'e'
+		}
+	}
+	stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32)
+}
+
+// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster
+func (stream *Stream) WriteFloat32Lossy(val float32) {
+	if val < 0 {
+		stream.writeByte('-')
+		val = -val
+	}
+	if val > 0x4ffffff {
+		stream.WriteFloat32(val)
+		return
+	}
+	precision := 6
+	exp := uint64(1000000) // 6
+	lval := uint64(float64(val)*float64(exp) + 0.5)
+	stream.WriteUint64(lval / exp)
+	fval := lval % exp
+	if fval == 0 {
+		return
+	}
+	stream.writeByte('.')
+	for p := precision - 1; p > 0 && fval < pow10[p]; p-- {
+		stream.writeByte('0')
+	}
+	stream.WriteUint64(fval)
+	for stream.buf[len(stream.buf)-1] == '0' {
+		stream.buf = stream.buf[:len(stream.buf)-1]
+	}
+}
+
+// WriteFloat64 write float64 to stream
+func (stream *Stream) WriteFloat64(val float64) {
+	abs := math.Abs(val)
+	fmt := byte('f')
+	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
+	if abs != 0 {
+		if abs < 1e-6 || abs >= 1e21 {
+			fmt = 'e'
+		}
+	}
+	stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64)
+}
+
+// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster
+func (stream *Stream) WriteFloat64Lossy(val float64) {
+	if val < 0 {
+		stream.writeByte('-')
+		val = -val
+	}
+	if val > 0x4ffffff {
+		stream.WriteFloat64(val)
+		return
+	}
+	precision := 6
+	exp := uint64(1000000) // 6
+	lval := uint64(val*float64(exp) + 0.5)
+	stream.WriteUint64(lval / exp)
+	fval := lval % exp
+	if fval == 0 {
+		return
+	}
+	stream.writeByte('.')
+	for p := precision - 1; p > 0 && fval < pow10[p]; p-- {
+		stream.writeByte('0')
+	}
+	stream.WriteUint64(fval)
+	for stream.buf[len(stream.buf)-1] == '0' {
+		stream.buf = stream.buf[:len(stream.buf)-1]
+	}
+}

+ 190 - 0
vendor/github.com/json-iterator/go/stream_int.go

@@ -0,0 +1,190 @@
+package jsoniter
+
+var digits []uint32
+
+func init() {
+	digits = make([]uint32, 1000)
+	for i := uint32(0); i < 1000; i++ {
+		digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0'
+		if i < 10 {
+			digits[i] += 2 << 24
+		} else if i < 100 {
+			digits[i] += 1 << 24
+		}
+	}
+}
+
+func writeFirstBuf(space []byte, v uint32) []byte {
+	start := v >> 24
+	if start == 0 {
+		space = append(space, byte(v>>16), byte(v>>8))
+	} else if start == 1 {
+		space = append(space, byte(v>>8))
+	}
+	space = append(space, byte(v))
+	return space
+}
+
+func writeBuf(buf []byte, v uint32) []byte {
+	return append(buf, byte(v>>16), byte(v>>8), byte(v))
+}
+
+// WriteUint8 write uint8 to stream
+func (stream *Stream) WriteUint8(val uint8) {
+	stream.buf = writeFirstBuf(stream.buf, digits[val])
+}
+
+// WriteInt8 write int8 to stream
+func (stream *Stream) WriteInt8(nval int8) {
+	var val uint8
+	if nval < 0 {
+		val = uint8(-nval)
+		stream.buf = append(stream.buf, '-')
+	} else {
+		val = uint8(nval)
+	}
+	stream.buf = writeFirstBuf(stream.buf, digits[val])
+}
+
+// WriteUint16 write uint16 to stream
+func (stream *Stream) WriteUint16(val uint16) {
+	q1 := val / 1000
+	if q1 == 0 {
+		stream.buf = writeFirstBuf(stream.buf, digits[val])
+		return
+	}
+	r1 := val - q1*1000
+	stream.buf = writeFirstBuf(stream.buf, digits[q1])
+	stream.buf = writeBuf(stream.buf, digits[r1])
+	return
+}
+
+// WriteInt16 write int16 to stream
+func (stream *Stream) WriteInt16(nval int16) {
+	var val uint16
+	if nval < 0 {
+		val = uint16(-nval)
+		stream.buf = append(stream.buf, '-')
+	} else {
+		val = uint16(nval)
+	}
+	stream.WriteUint16(val)
+}
+
+// WriteUint32 write uint32 to stream
+func (stream *Stream) WriteUint32(val uint32) {
+	q1 := val / 1000
+	if q1 == 0 {
+		stream.buf = writeFirstBuf(stream.buf, digits[val])
+		return
+	}
+	r1 := val - q1*1000
+	q2 := q1 / 1000
+	if q2 == 0 {
+		stream.buf = writeFirstBuf(stream.buf, digits[q1])
+		stream.buf = writeBuf(stream.buf, digits[r1])
+		return
+	}
+	r2 := q1 - q2*1000
+	q3 := q2 / 1000
+	if q3 == 0 {
+		stream.buf = writeFirstBuf(stream.buf, digits[q2])
+	} else {
+		r3 := q2 - q3*1000
+		stream.buf = append(stream.buf, byte(q3+'0'))
+		stream.buf = writeBuf(stream.buf, digits[r3])
+	}
+	stream.buf = writeBuf(stream.buf, digits[r2])
+	stream.buf = writeBuf(stream.buf, digits[r1])
+}
+
+// WriteInt32 write int32 to stream
+func (stream *Stream) WriteInt32(nval int32) {
+	var val uint32
+	if nval < 0 {
+		val = uint32(-nval)
+		stream.buf = append(stream.buf, '-')
+	} else {
+		val = uint32(nval)
+	}
+	stream.WriteUint32(val)
+}
+
+// WriteUint64 write uint64 to stream
+func (stream *Stream) WriteUint64(val uint64) {
+	q1 := val / 1000
+	if q1 == 0 {
+		stream.buf = writeFirstBuf(stream.buf, digits[val])
+		return
+	}
+	r1 := val - q1*1000
+	q2 := q1 / 1000
+	if q2 == 0 {
+		stream.buf = writeFirstBuf(stream.buf, digits[q1])
+		stream.buf = writeBuf(stream.buf, digits[r1])
+		return
+	}
+	r2 := q1 - q2*1000
+	q3 := q2 / 1000
+	if q3 == 0 {
+		stream.buf = writeFirstBuf(stream.buf, digits[q2])
+		stream.buf = writeBuf(stream.buf, digits[r2])
+		stream.buf = writeBuf(stream.buf, digits[r1])
+		return
+	}
+	r3 := q2 - q3*1000
+	q4 := q3 / 1000
+	if q4 == 0 {
+		stream.buf = writeFirstBuf(stream.buf, digits[q3])
+		stream.buf = writeBuf(stream.buf, digits[r3])
+		stream.buf = writeBuf(stream.buf, digits[r2])
+		stream.buf = writeBuf(stream.buf, digits[r1])
+		return
+	}
+	r4 := q3 - q4*1000
+	q5 := q4 / 1000
+	if q5 == 0 {
+		stream.buf = writeFirstBuf(stream.buf, digits[q4])
+		stream.buf = writeBuf(stream.buf, digits[r4])
+		stream.buf = writeBuf(stream.buf, digits[r3])
+		stream.buf = writeBuf(stream.buf, digits[r2])
+		stream.buf = writeBuf(stream.buf, digits[r1])
+		return
+	}
+	r5 := q4 - q5*1000
+	q6 := q5 / 1000
+	if q6 == 0 {
+		stream.buf = writeFirstBuf(stream.buf, digits[q5])
+	} else {
+		stream.buf = writeFirstBuf(stream.buf, digits[q6])
+		r6 := q5 - q6*1000
+		stream.buf = writeBuf(stream.buf, digits[r6])
+	}
+	stream.buf = writeBuf(stream.buf, digits[r5])
+	stream.buf = writeBuf(stream.buf, digits[r4])
+	stream.buf = writeBuf(stream.buf, digits[r3])
+	stream.buf = writeBuf(stream.buf, digits[r2])
+	stream.buf = writeBuf(stream.buf, digits[r1])
+}
+
+// WriteInt64 write int64 to stream
+func (stream *Stream) WriteInt64(nval int64) {
+	var val uint64
+	if nval < 0 {
+		val = uint64(-nval)
+		stream.buf = append(stream.buf, '-')
+	} else {
+		val = uint64(nval)
+	}
+	stream.WriteUint64(val)
+}
+
+// WriteInt write int to stream
+func (stream *Stream) WriteInt(val int) {
+	stream.WriteInt64(int64(val))
+}
+
+// WriteUint write uint to stream
+func (stream *Stream) WriteUint(val uint) {
+	stream.WriteUint64(uint64(val))
+}

+ 372 - 0
vendor/github.com/json-iterator/go/stream_str.go

@@ -0,0 +1,372 @@
+package jsoniter
+
+import (
+	"unicode/utf8"
+)
+
+// htmlSafeSet holds the value true if the ASCII character with the given
+// array position can be safely represented inside a JSON string, embedded
+// inside of HTML <script> tags, without any additional escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), the backslash character ("\"), HTML opening and closing
+// tags ("<" and ">"), and the ampersand ("&").
+var htmlSafeSet = [utf8.RuneSelf]bool{
+	' ':      true,
+	'!':      true,
+	'"':      false,
+	'#':      true,
+	'$':      true,
+	'%':      true,
+	'&':      false,
+	'\'':     true,
+	'(':      true,
+	')':      true,
+	'*':      true,
+	'+':      true,
+	',':      true,
+	'-':      true,
+	'.':      true,
+	'/':      true,
+	'0':      true,
+	'1':      true,
+	'2':      true,
+	'3':      true,
+	'4':      true,
+	'5':      true,
+	'6':      true,
+	'7':      true,
+	'8':      true,
+	'9':      true,
+	':':      true,
+	';':      true,
+	'<':      false,
+	'=':      true,
+	'>':      false,
+	'?':      true,
+	'@':      true,
+	'A':      true,
+	'B':      true,
+	'C':      true,
+	'D':      true,
+	'E':      true,
+	'F':      true,
+	'G':      true,
+	'H':      true,
+	'I':      true,
+	'J':      true,
+	'K':      true,
+	'L':      true,
+	'M':      true,
+	'N':      true,
+	'O':      true,
+	'P':      true,
+	'Q':      true,
+	'R':      true,
+	'S':      true,
+	'T':      true,
+	'U':      true,
+	'V':      true,
+	'W':      true,
+	'X':      true,
+	'Y':      true,
+	'Z':      true,
+	'[':      true,
+	'\\':     false,
+	']':      true,
+	'^':      true,
+	'_':      true,
+	'`':      true,
+	'a':      true,
+	'b':      true,
+	'c':      true,
+	'd':      true,
+	'e':      true,
+	'f':      true,
+	'g':      true,
+	'h':      true,
+	'i':      true,
+	'j':      true,
+	'k':      true,
+	'l':      true,
+	'm':      true,
+	'n':      true,
+	'o':      true,
+	'p':      true,
+	'q':      true,
+	'r':      true,
+	's':      true,
+	't':      true,
+	'u':      true,
+	'v':      true,
+	'w':      true,
+	'x':      true,
+	'y':      true,
+	'z':      true,
+	'{':      true,
+	'|':      true,
+	'}':      true,
+	'~':      true,
+	'\u007f': true,
+}
+
+// safeSet holds the value true if the ASCII character with the given array
+// position can be represented inside a JSON string without any further
+// escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), and the backslash character ("\").
+var safeSet = [utf8.RuneSelf]bool{
+	' ':      true,
+	'!':      true,
+	'"':      false,
+	'#':      true,
+	'$':      true,
+	'%':      true,
+	'&':      true,
+	'\'':     true,
+	'(':      true,
+	')':      true,
+	'*':      true,
+	'+':      true,
+	',':      true,
+	'-':      true,
+	'.':      true,
+	'/':      true,
+	'0':      true,
+	'1':      true,
+	'2':      true,
+	'3':      true,
+	'4':      true,
+	'5':      true,
+	'6':      true,
+	'7':      true,
+	'8':      true,
+	'9':      true,
+	':':      true,
+	';':      true,
+	'<':      true,
+	'=':      true,
+	'>':      true,
+	'?':      true,
+	'@':      true,
+	'A':      true,
+	'B':      true,
+	'C':      true,
+	'D':      true,
+	'E':      true,
+	'F':      true,
+	'G':      true,
+	'H':      true,
+	'I':      true,
+	'J':      true,
+	'K':      true,
+	'L':      true,
+	'M':      true,
+	'N':      true,
+	'O':      true,
+	'P':      true,
+	'Q':      true,
+	'R':      true,
+	'S':      true,
+	'T':      true,
+	'U':      true,
+	'V':      true,
+	'W':      true,
+	'X':      true,
+	'Y':      true,
+	'Z':      true,
+	'[':      true,
+	'\\':     false,
+	']':      true,
+	'^':      true,
+	'_':      true,
+	'`':      true,
+	'a':      true,
+	'b':      true,
+	'c':      true,
+	'd':      true,
+	'e':      true,
+	'f':      true,
+	'g':      true,
+	'h':      true,
+	'i':      true,
+	'j':      true,
+	'k':      true,
+	'l':      true,
+	'm':      true,
+	'n':      true,
+	'o':      true,
+	'p':      true,
+	'q':      true,
+	'r':      true,
+	's':      true,
+	't':      true,
+	'u':      true,
+	'v':      true,
+	'w':      true,
+	'x':      true,
+	'y':      true,
+	'z':      true,
+	'{':      true,
+	'|':      true,
+	'}':      true,
+	'~':      true,
+	'\u007f': true,
+}
+
+var hex = "0123456789abcdef"
+
+// WriteStringWithHTMLEscaped write string to stream with html special characters escaped
+func (stream *Stream) WriteStringWithHTMLEscaped(s string) {
+	valLen := len(s)
+	stream.buf = append(stream.buf, '"')
+	// write string, the fast path, without utf8 and escape support
+	i := 0
+	for ; i < valLen; i++ {
+		c := s[i]
+		if c < utf8.RuneSelf && htmlSafeSet[c] {
+			stream.buf = append(stream.buf, c)
+		} else {
+			break
+		}
+	}
+	if i == valLen {
+		stream.buf = append(stream.buf, '"')
+		return
+	}
+	writeStringSlowPathWithHTMLEscaped(stream, i, s, valLen)
+}
+
+func writeStringSlowPathWithHTMLEscaped(stream *Stream, i int, s string, valLen int) {
+	start := i
+	// for the remaining parts, we process them char by char
+	for i < valLen {
+		if b := s[i]; b < utf8.RuneSelf {
+			if htmlSafeSet[b] {
+				i++
+				continue
+			}
+			if start < i {
+				stream.WriteRaw(s[start:i])
+			}
+			switch b {
+			case '\\', '"':
+				stream.writeTwoBytes('\\', b)
+			case '\n':
+				stream.writeTwoBytes('\\', 'n')
+			case '\r':
+				stream.writeTwoBytes('\\', 'r')
+			case '\t':
+				stream.writeTwoBytes('\\', 't')
+			default:
+				// This encodes bytes < 0x20 except for \t, \n and \r.
+				// If escapeHTML is set, it also escapes <, >, and &
+				// because they can lead to security holes when
+				// user-controlled strings are rendered into JSON
+				// and served to some browsers.
+				stream.WriteRaw(`\u00`)
+				stream.writeTwoBytes(hex[b>>4], hex[b&0xF])
+			}
+			i++
+			start = i
+			continue
+		}
+		c, size := utf8.DecodeRuneInString(s[i:])
+		if c == utf8.RuneError && size == 1 {
+			if start < i {
+				stream.WriteRaw(s[start:i])
+			}
+			stream.WriteRaw(`\ufffd`)
+			i++
+			start = i
+			continue
+		}
+		// U+2028 is LINE SEPARATOR.
+		// U+2029 is PARAGRAPH SEPARATOR.
+		// They are both technically valid characters in JSON strings,
+		// but don't work in JSONP, which has to be evaluated as JavaScript,
+		// and can lead to security holes there. It is valid JSON to
+		// escape them, so we do so unconditionally.
+		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+		if c == '\u2028' || c == '\u2029' {
+			if start < i {
+				stream.WriteRaw(s[start:i])
+			}
+			stream.WriteRaw(`\u202`)
+			stream.writeByte(hex[c&0xF])
+			i += size
+			start = i
+			continue
+		}
+		i += size
+	}
+	if start < len(s) {
+		stream.WriteRaw(s[start:])
+	}
+	stream.writeByte('"')
+}
+
+// WriteString write string to stream without html escape
+func (stream *Stream) WriteString(s string) {
+	valLen := len(s)
+	stream.buf = append(stream.buf, '"')
+	// write string, the fast path, without utf8 and escape support
+	i := 0
+	for ; i < valLen; i++ {
+		c := s[i]
+		if c > 31 && c != '"' && c != '\\' {
+			stream.buf = append(stream.buf, c)
+		} else {
+			break
+		}
+	}
+	if i == valLen {
+		stream.buf = append(stream.buf, '"')
+		return
+	}
+	writeStringSlowPath(stream, i, s, valLen)
+}
+
+func writeStringSlowPath(stream *Stream, i int, s string, valLen int) {
+	start := i
+	// for the remaining parts, we process them char by char
+	for i < valLen {
+		if b := s[i]; b < utf8.RuneSelf {
+			if safeSet[b] {
+				i++
+				continue
+			}
+			if start < i {
+				stream.WriteRaw(s[start:i])
+			}
+			switch b {
+			case '\\', '"':
+				stream.writeTwoBytes('\\', b)
+			case '\n':
+				stream.writeTwoBytes('\\', 'n')
+			case '\r':
+				stream.writeTwoBytes('\\', 'r')
+			case '\t':
+				stream.writeTwoBytes('\\', 't')
+			default:
+				// This encodes bytes < 0x20 except for \t, \n and \r.
+				// If escapeHTML is set, it also escapes <, >, and &
+				// because they can lead to security holes when
+				// user-controlled strings are rendered into JSON
+				// and served to some browsers.
+				stream.WriteRaw(`\u00`)
+				stream.writeTwoBytes(hex[b>>4], hex[b&0xF])
+			}
+			i++
+			start = i
+			continue
+		}
+		i++
+		continue
+	}
+	if start < len(s) {
+		stream.WriteRaw(s[start:])
+	}
+	stream.writeByte('"')
+}

+ 201 - 0
vendor/github.com/modern-go/concurrent/LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 14 - 0
vendor/github.com/modern-go/concurrent/executor.go

@@ -0,0 +1,14 @@
+package concurrent
+
+import "context"
+
+// Executor replace go keyword to start a new goroutine
+// the goroutine should cancel itself if the context passed in has been cancelled
+// the goroutine started by the executor, is owned by the executor
+// we can cancel all executors owned by the executor just by stop the executor itself
+// however Executor interface does not Stop method, the one starting and owning executor
+// should use the concrete type of executor, instead of this interface.
+type Executor interface {
+	// Go starts a new goroutine controlled by the context
+	Go(handler func(ctx context.Context))
+}

+ 15 - 0
vendor/github.com/modern-go/concurrent/go_above_19.go

@@ -0,0 +1,15 @@
+//+build go1.9
+
+package concurrent
+
+import "sync"
+
+// Map is a wrapper for sync.Map introduced in go1.9
+type Map struct {
+	sync.Map
+}
+
+// NewMap creates a thread safe Map
+func NewMap() *Map {
+	return &Map{}
+}

+ 33 - 0
vendor/github.com/modern-go/concurrent/go_below_19.go

@@ -0,0 +1,33 @@
+//+build !go1.9
+
+package concurrent
+
+import "sync"
+
+// Map implements a thread safe map for go version below 1.9 using mutex
+type Map struct {
+	lock sync.RWMutex
+	data map[interface{}]interface{}
+}
+
+// NewMap creates a thread safe map
+func NewMap() *Map {
+	return &Map{
+		data: make(map[interface{}]interface{}, 32),
+	}
+}
+
+// Load is same as sync.Map Load
+func (m *Map) Load(key interface{}) (elem interface{}, found bool) {
+	m.lock.RLock()
+	elem, found = m.data[key]
+	m.lock.RUnlock()
+	return
+}
+
+// Load is same as sync.Map Store
+func (m *Map) Store(key interface{}, elem interface{}) {
+	m.lock.Lock()
+	m.data[key] = elem
+	m.lock.Unlock()
+}

+ 13 - 0
vendor/github.com/modern-go/concurrent/log.go

@@ -0,0 +1,13 @@
+package concurrent
+
+import (
+	"os"
+	"log"
+	"io/ioutil"
+)
+
+// ErrorLogger is used to print out error, can be set to writer other than stderr
+var ErrorLogger = log.New(os.Stderr, "", 0)
+
+// InfoLogger is used to print informational message, default to off
+var InfoLogger = log.New(ioutil.Discard, "", 0)

+ 119 - 0
vendor/github.com/modern-go/concurrent/unbounded_executor.go

@@ -0,0 +1,119 @@
+package concurrent
+
+import (
+	"context"
+	"fmt"
+	"runtime"
+	"runtime/debug"
+	"sync"
+	"time"
+	"reflect"
+)
+
+// HandlePanic logs goroutine panic by default
+var HandlePanic = func(recovered interface{}, funcName string) {
+	ErrorLogger.Println(fmt.Sprintf("%s panic: %v", funcName, recovered))
+	ErrorLogger.Println(string(debug.Stack()))
+}
+
+// UnboundedExecutor is a executor without limits on counts of alive goroutines
+// it tracks the goroutine started by it, and can cancel them when shutdown
+type UnboundedExecutor struct {
+	ctx                   context.Context
+	cancel                context.CancelFunc
+	activeGoroutinesMutex *sync.Mutex
+	activeGoroutines      map[string]int
+	HandlePanic           func(recovered interface{}, funcName string)
+}
+
+// GlobalUnboundedExecutor has the life cycle of the program itself
+// any goroutine want to be shutdown before main exit can be started from this executor
+// GlobalUnboundedExecutor expects the main function to call stop
+// it does not magically knows the main function exits
+var GlobalUnboundedExecutor = NewUnboundedExecutor()
+
+// NewUnboundedExecutor creates a new UnboundedExecutor,
+// UnboundedExecutor can not be created by &UnboundedExecutor{}
+// HandlePanic can be set with a callback to override global HandlePanic
+func NewUnboundedExecutor() *UnboundedExecutor {
+	ctx, cancel := context.WithCancel(context.TODO())
+	return &UnboundedExecutor{
+		ctx:                   ctx,
+		cancel:                cancel,
+		activeGoroutinesMutex: &sync.Mutex{},
+		activeGoroutines:      map[string]int{},
+	}
+}
+
+// Go starts a new goroutine and tracks its lifecycle.
+// Panic will be recovered and logged automatically, except for StopSignal
+func (executor *UnboundedExecutor) Go(handler func(ctx context.Context)) {
+	pc := reflect.ValueOf(handler).Pointer()
+	f := runtime.FuncForPC(pc)
+	funcName := f.Name()
+	file, line := f.FileLine(pc)
+	executor.activeGoroutinesMutex.Lock()
+	defer executor.activeGoroutinesMutex.Unlock()
+	startFrom := fmt.Sprintf("%s:%d", file, line)
+	executor.activeGoroutines[startFrom] += 1
+	go func() {
+		defer func() {
+			recovered := recover()
+			// if you want to quit a goroutine without trigger HandlePanic
+			// use runtime.Goexit() to quit
+			if recovered != nil {
+				if executor.HandlePanic == nil {
+					HandlePanic(recovered, funcName)
+				} else {
+					executor.HandlePanic(recovered, funcName)
+				}
+			}
+			executor.activeGoroutinesMutex.Lock()
+			executor.activeGoroutines[startFrom] -= 1
+			executor.activeGoroutinesMutex.Unlock()
+		}()
+		handler(executor.ctx)
+	}()
+}
+
+// Stop cancel all goroutines started by this executor without wait
+func (executor *UnboundedExecutor) Stop() {
+	executor.cancel()
+}
+
+// StopAndWaitForever cancel all goroutines started by this executor and
+// wait until all goroutines exited
+func (executor *UnboundedExecutor) StopAndWaitForever() {
+	executor.StopAndWait(context.Background())
+}
+
+// StopAndWait cancel all goroutines started by this executor and wait.
+// Wait can be cancelled by the context passed in.
+func (executor *UnboundedExecutor) StopAndWait(ctx context.Context) {
+	executor.cancel()
+	for {
+		oneHundredMilliseconds := time.NewTimer(time.Millisecond * 100)
+		select {
+		case <-oneHundredMilliseconds.C:
+			if executor.checkNoActiveGoroutines() {
+				return
+			}
+		case <-ctx.Done():
+			return
+		}
+	}
+}
+
+func (executor *UnboundedExecutor) checkNoActiveGoroutines() bool {
+	executor.activeGoroutinesMutex.Lock()
+	defer executor.activeGoroutinesMutex.Unlock()
+	for startFrom, count := range executor.activeGoroutines {
+		if count > 0 {
+			InfoLogger.Println("UnboundedExecutor is still waiting goroutines to quit",
+				"startFrom", startFrom,
+				"count", count)
+			return false
+		}
+	}
+	return true
+}

+ 201 - 0
vendor/github.com/modern-go/reflect2/LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 8 - 0
vendor/github.com/modern-go/reflect2/go_above_17.go

@@ -0,0 +1,8 @@
+//+build go1.7
+
+package reflect2
+
+import "unsafe"
+
+//go:linkname resolveTypeOff reflect.resolveTypeOff
+func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer

+ 14 - 0
vendor/github.com/modern-go/reflect2/go_above_19.go

@@ -0,0 +1,14 @@
+//+build go1.9
+
+package reflect2
+
+import (
+	"unsafe"
+)
+
+//go:linkname makemap reflect.makemap
+func makemap(rtype unsafe.Pointer, cap int) (m unsafe.Pointer)
+
+func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer {
+	return makemap(rtype, cap)
+}

+ 9 - 0
vendor/github.com/modern-go/reflect2/go_below_17.go

@@ -0,0 +1,9 @@
+//+build !go1.7
+
+package reflect2
+
+import "unsafe"
+
+func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
+	return nil
+}

+ 14 - 0
vendor/github.com/modern-go/reflect2/go_below_19.go

@@ -0,0 +1,14 @@
+//+build !go1.9
+
+package reflect2
+
+import (
+	"unsafe"
+)
+
+//go:linkname makemap reflect.makemap
+func makemap(rtype unsafe.Pointer) (m unsafe.Pointer)
+
+func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer {
+	return makemap(rtype)
+}

+ 298 - 0
vendor/github.com/modern-go/reflect2/reflect2.go

@@ -0,0 +1,298 @@
+package reflect2
+
+import (
+	"github.com/modern-go/concurrent"
+	"reflect"
+	"unsafe"
+)
+
+type Type interface {
+	Kind() reflect.Kind
+	// New return pointer to data of this type
+	New() interface{}
+	// UnsafeNew return the allocated space pointed by unsafe.Pointer
+	UnsafeNew() unsafe.Pointer
+	// PackEFace cast a unsafe pointer to object represented pointer
+	PackEFace(ptr unsafe.Pointer) interface{}
+	// Indirect dereference object represented pointer to this type
+	Indirect(obj interface{}) interface{}
+	// UnsafeIndirect dereference pointer to this type
+	UnsafeIndirect(ptr unsafe.Pointer) interface{}
+	// Type1 returns reflect.Type
+	Type1() reflect.Type
+	Implements(thatType Type) bool
+	String() string
+	RType() uintptr
+	// interface{} of this type has pointer like behavior
+	LikePtr() bool
+	IsNullable() bool
+	IsNil(obj interface{}) bool
+	UnsafeIsNil(ptr unsafe.Pointer) bool
+	Set(obj interface{}, val interface{})
+	UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer)
+	AssignableTo(anotherType Type) bool
+}
+
+type ListType interface {
+	Type
+	Elem() Type
+	SetIndex(obj interface{}, index int, elem interface{})
+	UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer)
+	GetIndex(obj interface{}, index int) interface{}
+	UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer
+}
+
+type ArrayType interface {
+	ListType
+	Len() int
+}
+
+type SliceType interface {
+	ListType
+	MakeSlice(length int, cap int) interface{}
+	UnsafeMakeSlice(length int, cap int) unsafe.Pointer
+	Grow(obj interface{}, newLength int)
+	UnsafeGrow(ptr unsafe.Pointer, newLength int)
+	Append(obj interface{}, elem interface{})
+	UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer)
+	LengthOf(obj interface{}) int
+	UnsafeLengthOf(ptr unsafe.Pointer) int
+	SetNil(obj interface{})
+	UnsafeSetNil(ptr unsafe.Pointer)
+	Cap(obj interface{}) int
+	UnsafeCap(ptr unsafe.Pointer) int
+}
+
+type StructType interface {
+	Type
+	NumField() int
+	Field(i int) StructField
+	FieldByName(name string) StructField
+	FieldByIndex(index []int) StructField
+	FieldByNameFunc(match func(string) bool) StructField
+}
+
+type StructField interface {
+	Offset() uintptr
+	Name() string
+	PkgPath() string
+	Type() Type
+	Tag() reflect.StructTag
+	Index() []int
+	Anonymous() bool
+	Set(obj interface{}, value interface{})
+	UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer)
+	Get(obj interface{}) interface{}
+	UnsafeGet(obj unsafe.Pointer) unsafe.Pointer
+}
+
+type MapType interface {
+	Type
+	Key() Type
+	Elem() Type
+	MakeMap(cap int) interface{}
+	UnsafeMakeMap(cap int) unsafe.Pointer
+	SetIndex(obj interface{}, key interface{}, elem interface{})
+	UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer)
+	TryGetIndex(obj interface{}, key interface{}) (interface{}, bool)
+	GetIndex(obj interface{}, key interface{}) interface{}
+	UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer
+	Iterate(obj interface{}) MapIterator
+	UnsafeIterate(obj unsafe.Pointer) MapIterator
+}
+
+type MapIterator interface {
+	HasNext() bool
+	Next() (key interface{}, elem interface{})
+	UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer)
+}
+
+type PtrType interface {
+	Type
+	Elem() Type
+}
+
+type InterfaceType interface {
+	NumMethod() int
+}
+
+type Config struct {
+	UseSafeImplementation bool
+}
+
+type API interface {
+	TypeOf(obj interface{}) Type
+	Type2(type1 reflect.Type) Type
+}
+
+var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze()
+var ConfigSafe = Config{UseSafeImplementation: true}.Froze()
+
+type frozenConfig struct {
+	useSafeImplementation bool
+	cache                 *concurrent.Map
+}
+
+func (cfg Config) Froze() *frozenConfig {
+	return &frozenConfig{
+		useSafeImplementation: cfg.UseSafeImplementation,
+		cache: concurrent.NewMap(),
+	}
+}
+
+func (cfg *frozenConfig) TypeOf(obj interface{}) Type {
+	cacheKey := uintptr(unpackEFace(obj).rtype)
+	typeObj, found := cfg.cache.Load(cacheKey)
+	if found {
+		return typeObj.(Type)
+	}
+	return cfg.Type2(reflect.TypeOf(obj))
+}
+
+func (cfg *frozenConfig) Type2(type1 reflect.Type) Type {
+	if type1 == nil {
+		return nil
+	}
+	cacheKey := uintptr(unpackEFace(type1).data)
+	typeObj, found := cfg.cache.Load(cacheKey)
+	if found {
+		return typeObj.(Type)
+	}
+	type2 := cfg.wrapType(type1)
+	cfg.cache.Store(cacheKey, type2)
+	return type2
+}
+
+func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type {
+	safeType := safeType{Type: type1, cfg: cfg}
+	switch type1.Kind() {
+	case reflect.Struct:
+		if cfg.useSafeImplementation {
+			return &safeStructType{safeType}
+		}
+		return newUnsafeStructType(cfg, type1)
+	case reflect.Array:
+		if cfg.useSafeImplementation {
+			return &safeSliceType{safeType}
+		}
+		return newUnsafeArrayType(cfg, type1)
+	case reflect.Slice:
+		if cfg.useSafeImplementation {
+			return &safeSliceType{safeType}
+		}
+		return newUnsafeSliceType(cfg, type1)
+	case reflect.Map:
+		if cfg.useSafeImplementation {
+			return &safeMapType{safeType}
+		}
+		return newUnsafeMapType(cfg, type1)
+	case reflect.Ptr, reflect.Chan, reflect.Func:
+		if cfg.useSafeImplementation {
+			return &safeMapType{safeType}
+		}
+		return newUnsafePtrType(cfg, type1)
+	case reflect.Interface:
+		if cfg.useSafeImplementation {
+			return &safeMapType{safeType}
+		}
+		if type1.NumMethod() == 0 {
+			return newUnsafeEFaceType(cfg, type1)
+		}
+		return newUnsafeIFaceType(cfg, type1)
+	default:
+		if cfg.useSafeImplementation {
+			return &safeType
+		}
+		return newUnsafeType(cfg, type1)
+	}
+}
+
+func TypeOf(obj interface{}) Type {
+	return ConfigUnsafe.TypeOf(obj)
+}
+
+func TypeOfPtr(obj interface{}) PtrType {
+	return TypeOf(obj).(PtrType)
+}
+
+func Type2(type1 reflect.Type) Type {
+	if type1 == nil {
+		return nil
+	}
+	return ConfigUnsafe.Type2(type1)
+}
+
+func PtrTo(typ Type) Type {
+	return Type2(reflect.PtrTo(typ.Type1()))
+}
+
+func PtrOf(obj interface{}) unsafe.Pointer {
+	return unpackEFace(obj).data
+}
+
+func RTypeOf(obj interface{}) uintptr {
+	return uintptr(unpackEFace(obj).rtype)
+}
+
+func IsNil(obj interface{}) bool {
+	if obj == nil {
+		return true
+	}
+	return unpackEFace(obj).data == nil
+}
+
+func IsNullable(kind reflect.Kind) bool {
+	switch kind {
+	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface:
+		return true
+	}
+	return false
+}
+
+func likePtrKind(kind reflect.Kind) bool {
+	switch kind {
+	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func:
+		return true
+	}
+	return false
+}
+
+func likePtrType(typ reflect.Type) bool {
+	if likePtrKind(typ.Kind()) {
+		return true
+	}
+	if typ.Kind() == reflect.Struct {
+		if typ.NumField() != 1 {
+			return false
+		}
+		return likePtrType(typ.Field(0).Type)
+	}
+	if typ.Kind() == reflect.Array {
+		if typ.Len() != 1 {
+			return false
+		}
+		return likePtrType(typ.Elem())
+	}
+	return false
+}
+
+// NoEscape hides a pointer from escape analysis.  noescape is
+// the identity function but escape analysis doesn't think the
+// output depends on the input.  noescape is inlined and currently
+// compiles down to zero instructions.
+// USE CAREFULLY!
+//go:nosplit
+func NoEscape(p unsafe.Pointer) unsafe.Pointer {
+	x := uintptr(p)
+	return unsafe.Pointer(x ^ 0)
+}
+
+func UnsafeCastString(str string) []byte {
+	stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str))
+	sliceHeader := &reflect.SliceHeader{
+		Data: stringHeader.Data,
+		Cap: stringHeader.Len,
+		Len: stringHeader.Len,
+	}
+	return *(*[]byte)(unsafe.Pointer(sliceHeader))
+}

+ 0 - 0
vendor/github.com/modern-go/reflect2/reflect2_amd64.s


+ 30 - 0
vendor/github.com/modern-go/reflect2/reflect2_kind.go

@@ -0,0 +1,30 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+// DefaultTypeOfKind return the non aliased default type for the kind
+func DefaultTypeOfKind(kind reflect.Kind) Type {
+	return kindTypes[kind]
+}
+
+var kindTypes = map[reflect.Kind]Type{
+	reflect.Bool:          TypeOf(true),
+	reflect.Uint8:         TypeOf(uint8(0)),
+	reflect.Int8:          TypeOf(int8(0)),
+	reflect.Uint16:        TypeOf(uint16(0)),
+	reflect.Int16:         TypeOf(int16(0)),
+	reflect.Uint32:        TypeOf(uint32(0)),
+	reflect.Int32:         TypeOf(int32(0)),
+	reflect.Uint64:        TypeOf(uint64(0)),
+	reflect.Int64:         TypeOf(int64(0)),
+	reflect.Uint:          TypeOf(uint(0)),
+	reflect.Int:           TypeOf(int(0)),
+	reflect.Float32:       TypeOf(float32(0)),
+	reflect.Float64:       TypeOf(float64(0)),
+	reflect.Uintptr:       TypeOf(uintptr(0)),
+	reflect.String:        TypeOf(""),
+	reflect.UnsafePointer: TypeOf(unsafe.Pointer(nil)),
+}

+ 0 - 0
vendor/github.com/modern-go/reflect2/relfect2_386.s


+ 0 - 0
vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s


+ 0 - 0
vendor/github.com/modern-go/reflect2/relfect2_arm.s


+ 0 - 0
vendor/github.com/modern-go/reflect2/relfect2_arm64.s


+ 0 - 0
vendor/github.com/modern-go/reflect2/relfect2_mips64x.s


+ 0 - 0
vendor/github.com/modern-go/reflect2/relfect2_mipsx.s


+ 0 - 0
vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s


+ 0 - 0
vendor/github.com/modern-go/reflect2/relfect2_s390x.s


+ 58 - 0
vendor/github.com/modern-go/reflect2/safe_field.go

@@ -0,0 +1,58 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type safeField struct {
+	reflect.StructField
+}
+
+func (field *safeField) Offset() uintptr {
+	return field.StructField.Offset
+}
+
+func (field *safeField) Name() string {
+	return field.StructField.Name
+}
+
+func (field *safeField) PkgPath() string {
+	return field.StructField.PkgPath
+}
+
+func (field *safeField) Type() Type {
+	panic("not implemented")
+}
+
+func (field *safeField) Tag() reflect.StructTag {
+	return field.StructField.Tag
+}
+
+func (field *safeField) Index() []int {
+	return field.StructField.Index
+}
+
+func (field *safeField) Anonymous() bool {
+	return field.StructField.Anonymous
+}
+
+func (field *safeField) Set(obj interface{}, value interface{}) {
+	val := reflect.ValueOf(obj).Elem()
+	val.FieldByIndex(field.Index()).Set(reflect.ValueOf(value).Elem())
+}
+
+func (field *safeField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) {
+	panic("unsafe operation is not supported")
+}
+
+func (field *safeField) Get(obj interface{}) interface{} {
+	val := reflect.ValueOf(obj).Elem().FieldByIndex(field.Index())
+	ptr := reflect.New(val.Type())
+	ptr.Elem().Set(val)
+	return ptr.Interface()
+}
+
+func (field *safeField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer {
+	panic("does not support unsafe operation")
+}

+ 101 - 0
vendor/github.com/modern-go/reflect2/safe_map.go

@@ -0,0 +1,101 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type safeMapType struct {
+	safeType
+}
+
+func (type2 *safeMapType) Key() Type {
+	return type2.safeType.cfg.Type2(type2.Type.Key())
+}
+
+func (type2 *safeMapType) MakeMap(cap int) interface{} {
+	ptr := reflect.New(type2.Type)
+	ptr.Elem().Set(reflect.MakeMap(type2.Type))
+	return ptr.Interface()
+}
+
+func (type2 *safeMapType) UnsafeMakeMap(cap int) unsafe.Pointer {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) {
+	keyVal := reflect.ValueOf(key)
+	elemVal := reflect.ValueOf(elem)
+	val := reflect.ValueOf(obj)
+	val.Elem().SetMapIndex(keyVal.Elem(), elemVal.Elem())
+}
+
+func (type2 *safeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) {
+	keyVal := reflect.ValueOf(key)
+	if key == nil {
+		keyVal = reflect.New(type2.Type.Key()).Elem()
+	}
+	val := reflect.ValueOf(obj).MapIndex(keyVal)
+	if !val.IsValid() {
+		return nil, false
+	}
+	return val.Interface(), true
+}
+
+func (type2 *safeMapType) GetIndex(obj interface{}, key interface{}) interface{} {
+	val := reflect.ValueOf(obj).Elem()
+	keyVal := reflect.ValueOf(key).Elem()
+	elemVal := val.MapIndex(keyVal)
+	if !elemVal.IsValid() {
+		ptr := reflect.New(reflect.PtrTo(val.Type().Elem()))
+		return ptr.Elem().Interface()
+	}
+	ptr := reflect.New(elemVal.Type())
+	ptr.Elem().Set(elemVal)
+	return ptr.Interface()
+}
+
+func (type2 *safeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeMapType) Iterate(obj interface{}) MapIterator {
+	m := reflect.ValueOf(obj).Elem()
+	return &safeMapIterator{
+		m:    m,
+		keys: m.MapKeys(),
+	}
+}
+
+func (type2 *safeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
+	panic("does not support unsafe operation")
+}
+
+type safeMapIterator struct {
+	i    int
+	m    reflect.Value
+	keys []reflect.Value
+}
+
+func (iter *safeMapIterator) HasNext() bool {
+	return iter.i != len(iter.keys)
+}
+
+func (iter *safeMapIterator) Next() (interface{}, interface{}) {
+	key := iter.keys[iter.i]
+	elem := iter.m.MapIndex(key)
+	iter.i += 1
+	keyPtr := reflect.New(key.Type())
+	keyPtr.Elem().Set(key)
+	elemPtr := reflect.New(elem.Type())
+	elemPtr.Elem().Set(elem)
+	return keyPtr.Interface(), elemPtr.Interface()
+}
+
+func (iter *safeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) {
+	panic("does not support unsafe operation")
+}

+ 92 - 0
vendor/github.com/modern-go/reflect2/safe_slice.go

@@ -0,0 +1,92 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type safeSliceType struct {
+	safeType
+}
+
+func (type2 *safeSliceType) SetIndex(obj interface{}, index int, value interface{}) {
+	val := reflect.ValueOf(obj).Elem()
+	elem := reflect.ValueOf(value).Elem()
+	val.Index(index).Set(elem)
+}
+
+func (type2 *safeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, value unsafe.Pointer) {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeSliceType) GetIndex(obj interface{}, index int) interface{} {
+	val := reflect.ValueOf(obj).Elem()
+	elem := val.Index(index)
+	ptr := reflect.New(elem.Type())
+	ptr.Elem().Set(elem)
+	return ptr.Interface()
+}
+
+func (type2 *safeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeSliceType) MakeSlice(length int, cap int) interface{} {
+	val := reflect.MakeSlice(type2.Type, length, cap)
+	ptr := reflect.New(val.Type())
+	ptr.Elem().Set(val)
+	return ptr.Interface()
+}
+
+func (type2 *safeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeSliceType) Grow(obj interface{}, newLength int) {
+	oldCap := type2.Cap(obj)
+	oldSlice := reflect.ValueOf(obj).Elem()
+	delta := newLength - oldCap
+	deltaVals := make([]reflect.Value, delta)
+	newSlice := reflect.Append(oldSlice, deltaVals...)
+	oldSlice.Set(newSlice)
+}
+
+func (type2 *safeSliceType) UnsafeGrow(ptr unsafe.Pointer, newLength int) {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeSliceType) Append(obj interface{}, elem interface{}) {
+	val := reflect.ValueOf(obj).Elem()
+	elemVal := reflect.ValueOf(elem).Elem()
+	newVal := reflect.Append(val, elemVal)
+	val.Set(newVal)
+}
+
+func (type2 *safeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeSliceType) SetNil(obj interface{}) {
+	val := reflect.ValueOf(obj).Elem()
+	val.Set(reflect.Zero(val.Type()))
+}
+
+func (type2 *safeSliceType) UnsafeSetNil(ptr unsafe.Pointer) {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeSliceType) LengthOf(obj interface{}) int {
+	return reflect.ValueOf(obj).Elem().Len()
+}
+
+func (type2 *safeSliceType) UnsafeLengthOf(ptr unsafe.Pointer) int {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeSliceType) Cap(obj interface{}) int {
+	return reflect.ValueOf(obj).Elem().Cap()
+}
+
+func (type2 *safeSliceType) UnsafeCap(ptr unsafe.Pointer) int {
+	panic("does not support unsafe operation")
+}

+ 29 - 0
vendor/github.com/modern-go/reflect2/safe_struct.go

@@ -0,0 +1,29 @@
+package reflect2
+
+type safeStructType struct {
+	safeType
+}
+
+func (type2 *safeStructType) FieldByName(name string) StructField {
+	field, found := type2.Type.FieldByName(name)
+	if !found {
+		panic("field " + name + " not found")
+	}
+	return &safeField{StructField: field}
+}
+
+func (type2 *safeStructType) Field(i int) StructField {
+	return &safeField{StructField: type2.Type.Field(i)}
+}
+
+func (type2 *safeStructType) FieldByIndex(index []int) StructField {
+	return &safeField{StructField: type2.Type.FieldByIndex(index)}
+}
+
+func (type2 *safeStructType) FieldByNameFunc(match func(string) bool) StructField {
+	field, found := type2.Type.FieldByNameFunc(match)
+	if !found {
+		panic("field match condition not found in " + type2.Type.String())
+	}
+	return &safeField{StructField: field}
+}

+ 78 - 0
vendor/github.com/modern-go/reflect2/safe_type.go

@@ -0,0 +1,78 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type safeType struct {
+	reflect.Type
+	cfg *frozenConfig
+}
+
+func (type2 *safeType) New() interface{} {
+	return reflect.New(type2.Type).Interface()
+}
+
+func (type2 *safeType) UnsafeNew() unsafe.Pointer {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeType) Elem() Type {
+	return type2.cfg.Type2(type2.Type.Elem())
+}
+
+func (type2 *safeType) Type1() reflect.Type {
+	return type2.Type
+}
+
+func (type2 *safeType) PackEFace(ptr unsafe.Pointer) interface{} {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeType) Implements(thatType Type) bool {
+	return type2.Type.Implements(thatType.Type1())
+}
+
+func (type2 *safeType) RType() uintptr {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeType) Indirect(obj interface{}) interface{} {
+	return reflect.Indirect(reflect.ValueOf(obj)).Interface()
+}
+
+func (type2 *safeType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeType) LikePtr() bool {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeType) IsNullable() bool {
+	return IsNullable(type2.Kind())
+}
+
+func (type2 *safeType) IsNil(obj interface{}) bool {
+	if obj == nil {
+		return true
+	}
+	return reflect.ValueOf(obj).Elem().IsNil()
+}
+
+func (type2 *safeType) UnsafeIsNil(ptr unsafe.Pointer) bool {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeType) Set(obj interface{}, val interface{}) {
+	reflect.ValueOf(obj).Elem().Set(reflect.ValueOf(val).Elem())
+}
+
+func (type2 *safeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) {
+	panic("does not support unsafe operation")
+}
+
+func (type2 *safeType) AssignableTo(anotherType Type) bool {
+	return type2.Type1().AssignableTo(anotherType.Type1())
+}

+ 113 - 0
vendor/github.com/modern-go/reflect2/type_map.go

@@ -0,0 +1,113 @@
+package reflect2
+
+import (
+	"reflect"
+	"runtime"
+	"strings"
+	"sync"
+	"unsafe"
+)
+
+// typelinks1 for 1.5 ~ 1.6
+//go:linkname typelinks1 reflect.typelinks
+func typelinks1() [][]unsafe.Pointer
+
+// typelinks2 for 1.7 ~
+//go:linkname typelinks2 reflect.typelinks
+func typelinks2() (sections []unsafe.Pointer, offset [][]int32)
+
+// initOnce guards initialization of types and packages
+var initOnce sync.Once
+
+var types map[string]reflect.Type
+var packages map[string]map[string]reflect.Type
+
+// discoverTypes initializes types and packages
+func discoverTypes() {
+	types = make(map[string]reflect.Type)
+	packages = make(map[string]map[string]reflect.Type)
+
+	ver := runtime.Version()
+	if ver == "go1.5" || strings.HasPrefix(ver, "go1.5.") {
+		loadGo15Types()
+	} else if ver == "go1.6" || strings.HasPrefix(ver, "go1.6.") {
+		loadGo15Types()
+	} else {
+		loadGo17Types()
+	}
+}
+
+func loadGo15Types() {
+	var obj interface{} = reflect.TypeOf(0)
+	typePtrss := typelinks1()
+	for _, typePtrs := range typePtrss {
+		for _, typePtr := range typePtrs {
+			(*emptyInterface)(unsafe.Pointer(&obj)).word = typePtr
+			typ := obj.(reflect.Type)
+			if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
+				loadedType := typ.Elem()
+				pkgTypes := packages[loadedType.PkgPath()]
+				if pkgTypes == nil {
+					pkgTypes = map[string]reflect.Type{}
+					packages[loadedType.PkgPath()] = pkgTypes
+				}
+				types[loadedType.String()] = loadedType
+				pkgTypes[loadedType.Name()] = loadedType
+			}
+			if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Ptr &&
+				typ.Elem().Elem().Kind() == reflect.Struct {
+				loadedType := typ.Elem().Elem()
+				pkgTypes := packages[loadedType.PkgPath()]
+				if pkgTypes == nil {
+					pkgTypes = map[string]reflect.Type{}
+					packages[loadedType.PkgPath()] = pkgTypes
+				}
+				types[loadedType.String()] = loadedType
+				pkgTypes[loadedType.Name()] = loadedType
+			}
+		}
+	}
+}
+
+func loadGo17Types() {
+	var obj interface{} = reflect.TypeOf(0)
+	sections, offset := typelinks2()
+	for i, offs := range offset {
+		rodata := sections[i]
+		for _, off := range offs {
+			(*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off)
+			typ := obj.(reflect.Type)
+			if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
+				loadedType := typ.Elem()
+				pkgTypes := packages[loadedType.PkgPath()]
+				if pkgTypes == nil {
+					pkgTypes = map[string]reflect.Type{}
+					packages[loadedType.PkgPath()] = pkgTypes
+				}
+				types[loadedType.String()] = loadedType
+				pkgTypes[loadedType.Name()] = loadedType
+			}
+		}
+	}
+}
+
+type emptyInterface struct {
+	typ  unsafe.Pointer
+	word unsafe.Pointer
+}
+
+// TypeByName return the type by its name, just like Class.forName in java
+func TypeByName(typeName string) Type {
+	initOnce.Do(discoverTypes)
+	return Type2(types[typeName])
+}
+
+// TypeByPackageName return the type by its package and name
+func TypeByPackageName(pkgPath string, name string) Type {
+	initOnce.Do(discoverTypes)
+	pkgTypes := packages[pkgPath]
+	if pkgTypes == nil {
+		return nil
+	}
+	return Type2(pkgTypes[name])
+}

+ 65 - 0
vendor/github.com/modern-go/reflect2/unsafe_array.go

@@ -0,0 +1,65 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type UnsafeArrayType struct {
+	unsafeType
+	elemRType  unsafe.Pointer
+	pElemRType unsafe.Pointer
+	elemSize   uintptr
+	likePtr    bool
+}
+
+func newUnsafeArrayType(cfg *frozenConfig, type1 reflect.Type) *UnsafeArrayType {
+	return &UnsafeArrayType{
+		unsafeType: *newUnsafeType(cfg, type1),
+		elemRType:  unpackEFace(type1.Elem()).data,
+		pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data,
+		elemSize:   type1.Elem().Size(),
+		likePtr:    likePtrType(type1),
+	}
+}
+
+func (type2 *UnsafeArrayType) LikePtr() bool {
+	return type2.likePtr
+}
+
+func (type2 *UnsafeArrayType) Indirect(obj interface{}) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIndirect(objEFace.data)
+}
+
+func (type2 *UnsafeArrayType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
+	if type2.likePtr {
+		return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr))
+	}
+	return packEFace(type2.rtype, ptr)
+}
+
+func (type2 *UnsafeArrayType) SetIndex(obj interface{}, index int, elem interface{}) {
+	objEFace := unpackEFace(obj)
+	assertType("ArrayType.SetIndex argument 1", type2.ptrRType, objEFace.rtype)
+	elemEFace := unpackEFace(elem)
+	assertType("ArrayType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype)
+	type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data)
+}
+
+func (type2 *UnsafeArrayType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) {
+	elemPtr := arrayAt(obj, index, type2.elemSize, "i < s.Len")
+	typedmemmove(type2.elemRType, elemPtr, elem)
+}
+
+func (type2 *UnsafeArrayType) GetIndex(obj interface{}, index int) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("ArrayType.GetIndex argument 1", type2.ptrRType, objEFace.rtype)
+	elemPtr := type2.UnsafeGetIndex(objEFace.data, index)
+	return packEFace(type2.pElemRType, elemPtr)
+}
+
+func (type2 *UnsafeArrayType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer {
+	return arrayAt(obj, index, type2.elemSize, "i < s.Len")
+}

+ 59 - 0
vendor/github.com/modern-go/reflect2/unsafe_eface.go

@@ -0,0 +1,59 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type eface struct {
+	rtype unsafe.Pointer
+	data  unsafe.Pointer
+}
+
+func unpackEFace(obj interface{}) *eface {
+	return (*eface)(unsafe.Pointer(&obj))
+}
+
+func packEFace(rtype unsafe.Pointer, data unsafe.Pointer) interface{} {
+	var i interface{}
+	e := (*eface)(unsafe.Pointer(&i))
+	e.rtype = rtype
+	e.data = data
+	return i
+}
+
+type UnsafeEFaceType struct {
+	unsafeType
+}
+
+func newUnsafeEFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeEFaceType {
+	return &UnsafeEFaceType{
+		unsafeType: *newUnsafeType(cfg, type1),
+	}
+}
+
+func (type2 *UnsafeEFaceType) IsNil(obj interface{}) bool {
+	if obj == nil {
+		return true
+	}
+	objEFace := unpackEFace(obj)
+	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIsNil(objEFace.data)
+}
+
+func (type2 *UnsafeEFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool {
+	if ptr == nil {
+		return true
+	}
+	return unpackEFace(*(*interface{})(ptr)).data == nil
+}
+
+func (type2 *UnsafeEFaceType) Indirect(obj interface{}) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIndirect(objEFace.data)
+}
+
+func (type2 *UnsafeEFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
+	return *(*interface{})(ptr)
+}

+ 74 - 0
vendor/github.com/modern-go/reflect2/unsafe_field.go

@@ -0,0 +1,74 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type UnsafeStructField struct {
+	reflect.StructField
+	structType *UnsafeStructType
+	rtype      unsafe.Pointer
+	ptrRType   unsafe.Pointer
+}
+
+func newUnsafeStructField(structType *UnsafeStructType, structField reflect.StructField) *UnsafeStructField {
+	return &UnsafeStructField{
+		StructField: structField,
+		rtype:       unpackEFace(structField.Type).data,
+		ptrRType:    unpackEFace(reflect.PtrTo(structField.Type)).data,
+		structType:  structType,
+	}
+}
+
+func (field *UnsafeStructField) Offset() uintptr {
+	return field.StructField.Offset
+}
+
+func (field *UnsafeStructField) Name() string {
+	return field.StructField.Name
+}
+
+func (field *UnsafeStructField) PkgPath() string {
+	return field.StructField.PkgPath
+}
+
+func (field *UnsafeStructField) Type() Type {
+	return field.structType.cfg.Type2(field.StructField.Type)
+}
+
+func (field *UnsafeStructField) Tag() reflect.StructTag {
+	return field.StructField.Tag
+}
+
+func (field *UnsafeStructField) Index() []int {
+	return field.StructField.Index
+}
+
+func (field *UnsafeStructField) Anonymous() bool {
+	return field.StructField.Anonymous
+}
+
+func (field *UnsafeStructField) Set(obj interface{}, value interface{}) {
+	objEFace := unpackEFace(obj)
+	assertType("StructField.SetIndex argument 1", field.structType.ptrRType, objEFace.rtype)
+	valueEFace := unpackEFace(value)
+	assertType("StructField.SetIndex argument 2", field.ptrRType, valueEFace.rtype)
+	field.UnsafeSet(objEFace.data, valueEFace.data)
+}
+
+func (field *UnsafeStructField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) {
+	fieldPtr := add(obj, field.StructField.Offset, "same as non-reflect &v.field")
+	typedmemmove(field.rtype, fieldPtr, value)
+}
+
+func (field *UnsafeStructField) Get(obj interface{}) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("StructField.GetIndex argument 1", field.structType.ptrRType, objEFace.rtype)
+	value := field.UnsafeGet(objEFace.data)
+	return packEFace(field.ptrRType, value)
+}
+
+func (field *UnsafeStructField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer {
+	return add(obj, field.StructField.Offset, "same as non-reflect &v.field")
+}

+ 64 - 0
vendor/github.com/modern-go/reflect2/unsafe_iface.go

@@ -0,0 +1,64 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type iface struct {
+	itab *itab
+	data unsafe.Pointer
+}
+
+type itab struct {
+	ignore unsafe.Pointer
+	rtype  unsafe.Pointer
+}
+
+func IFaceToEFace(ptr unsafe.Pointer) interface{} {
+	iface := (*iface)(ptr)
+	if iface.itab == nil {
+		return nil
+	}
+	return packEFace(iface.itab.rtype, iface.data)
+}
+
+type UnsafeIFaceType struct {
+	unsafeType
+}
+
+func newUnsafeIFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeIFaceType {
+	return &UnsafeIFaceType{
+		unsafeType: *newUnsafeType(cfg, type1),
+	}
+}
+
+func (type2 *UnsafeIFaceType) Indirect(obj interface{}) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIndirect(objEFace.data)
+}
+
+func (type2 *UnsafeIFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
+	return IFaceToEFace(ptr)
+}
+
+func (type2 *UnsafeIFaceType) IsNil(obj interface{}) bool {
+	if obj == nil {
+		return true
+	}
+	objEFace := unpackEFace(obj)
+	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIsNil(objEFace.data)
+}
+
+func (type2 *UnsafeIFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool {
+	if ptr == nil {
+		return true
+	}
+	iface := (*iface)(ptr)
+	if iface.itab == nil {
+		return true
+	}
+	return false
+}

+ 70 - 0
vendor/github.com/modern-go/reflect2/unsafe_link.go

@@ -0,0 +1,70 @@
+package reflect2
+
+import "unsafe"
+
+//go:linkname unsafe_New reflect.unsafe_New
+func unsafe_New(rtype unsafe.Pointer) unsafe.Pointer
+
+//go:linkname typedmemmove reflect.typedmemmove
+func typedmemmove(rtype unsafe.Pointer, dst, src unsafe.Pointer)
+
+//go:linkname unsafe_NewArray reflect.unsafe_NewArray
+func unsafe_NewArray(rtype unsafe.Pointer, length int) unsafe.Pointer
+
+// typedslicecopy copies a slice of elemType values from src to dst,
+// returning the number of elements copied.
+//go:linkname typedslicecopy reflect.typedslicecopy
+//go:noescape
+func typedslicecopy(elemType unsafe.Pointer, dst, src sliceHeader) int
+
+//go:linkname mapassign reflect.mapassign
+//go:noescape
+func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key, val unsafe.Pointer)
+
+//go:linkname mapaccess reflect.mapaccess
+//go:noescape
+func mapaccess(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
+
+// m escapes into the return value, but the caller of mapiterinit
+// doesn't let the return value escape.
+//go:noescape
+//go:linkname mapiterinit reflect.mapiterinit
+func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) *hiter
+
+//go:noescape
+//go:linkname mapiternext reflect.mapiternext
+func mapiternext(it *hiter)
+
+//go:linkname ifaceE2I reflect.ifaceE2I
+func ifaceE2I(rtype unsafe.Pointer, src interface{}, dst unsafe.Pointer)
+
+// A hash iteration structure.
+// If you modify hiter, also change cmd/internal/gc/reflect.go to indicate
+// the layout of this structure.
+type hiter struct {
+	key   unsafe.Pointer // Must be in first position.  Write nil to indicate iteration end (see cmd/internal/gc/range.go).
+	value unsafe.Pointer // Must be in second position (see cmd/internal/gc/range.go).
+	// rest fields are ignored
+}
+
+// add returns p+x.
+//
+// The whySafe string is ignored, so that the function still inlines
+// as efficiently as p+x, but all call sites should use the string to
+// record why the addition is safe, which is to say why the addition
+// does not cause x to advance to the very end of p's allocation
+// and therefore point incorrectly at the next block in memory.
+func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
+	return unsafe.Pointer(uintptr(p) + x)
+}
+
+// arrayAt returns the i-th element of p,
+// an array whose elements are eltSize bytes wide.
+// The array pointed at by p must have at least i+1 elements:
+// it is invalid (but impossible to check here) to pass i >= len,
+// because then the result will point outside the array.
+// whySafe must explain why i < len. (Passing "i < len" is fine;
+// the benefit is to surface this assumption at the call site.)
+func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
+	return add(p, uintptr(i)*eltSize, "i < len")
+}

+ 138 - 0
vendor/github.com/modern-go/reflect2/unsafe_map.go

@@ -0,0 +1,138 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type UnsafeMapType struct {
+	unsafeType
+	pKeyRType  unsafe.Pointer
+	pElemRType unsafe.Pointer
+}
+
+func newUnsafeMapType(cfg *frozenConfig, type1 reflect.Type) MapType {
+	return &UnsafeMapType{
+		unsafeType: *newUnsafeType(cfg, type1),
+		pKeyRType:  unpackEFace(reflect.PtrTo(type1.Key())).data,
+		pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data,
+	}
+}
+
+func (type2 *UnsafeMapType) IsNil(obj interface{}) bool {
+	if obj == nil {
+		return true
+	}
+	objEFace := unpackEFace(obj)
+	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIsNil(objEFace.data)
+}
+
+func (type2 *UnsafeMapType) UnsafeIsNil(ptr unsafe.Pointer) bool {
+	if ptr == nil {
+		return true
+	}
+	return *(*unsafe.Pointer)(ptr) == nil
+}
+
+func (type2 *UnsafeMapType) LikePtr() bool {
+	return true
+}
+
+func (type2 *UnsafeMapType) Indirect(obj interface{}) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("MapType.Indirect argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIndirect(objEFace.data)
+}
+
+func (type2 *UnsafeMapType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
+	return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr))
+}
+
+func (type2 *UnsafeMapType) Key() Type {
+	return type2.cfg.Type2(type2.Type.Key())
+}
+
+func (type2 *UnsafeMapType) MakeMap(cap int) interface{} {
+	return packEFace(type2.ptrRType, type2.UnsafeMakeMap(cap))
+}
+
+func (type2 *UnsafeMapType) UnsafeMakeMap(cap int) unsafe.Pointer {
+	m := makeMapWithSize(type2.rtype, cap)
+	return unsafe.Pointer(&m)
+}
+
+func (type2 *UnsafeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) {
+	objEFace := unpackEFace(obj)
+	assertType("MapType.SetIndex argument 1", type2.ptrRType, objEFace.rtype)
+	keyEFace := unpackEFace(key)
+	assertType("MapType.SetIndex argument 2", type2.pKeyRType, keyEFace.rtype)
+	elemEFace := unpackEFace(elem)
+	assertType("MapType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype)
+	type2.UnsafeSetIndex(objEFace.data, keyEFace.data, elemEFace.data)
+}
+
+func (type2 *UnsafeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) {
+	mapassign(type2.rtype, *(*unsafe.Pointer)(obj), key, elem)
+}
+
+func (type2 *UnsafeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) {
+	objEFace := unpackEFace(obj)
+	assertType("MapType.TryGetIndex argument 1", type2.ptrRType, objEFace.rtype)
+	keyEFace := unpackEFace(key)
+	assertType("MapType.TryGetIndex argument 2", type2.pKeyRType, keyEFace.rtype)
+	elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data)
+	if elemPtr == nil {
+		return nil, false
+	}
+	return packEFace(type2.pElemRType, elemPtr), true
+}
+
+func (type2 *UnsafeMapType) GetIndex(obj interface{}, key interface{}) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("MapType.GetIndex argument 1", type2.ptrRType, objEFace.rtype)
+	keyEFace := unpackEFace(key)
+	assertType("MapType.GetIndex argument 2", type2.pKeyRType, keyEFace.rtype)
+	elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data)
+	return packEFace(type2.pElemRType, elemPtr)
+}
+
+func (type2 *UnsafeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer {
+	return mapaccess(type2.rtype, *(*unsafe.Pointer)(obj), key)
+}
+
+func (type2 *UnsafeMapType) Iterate(obj interface{}) MapIterator {
+	objEFace := unpackEFace(obj)
+	assertType("MapType.Iterate argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIterate(objEFace.data)
+}
+
+func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
+	return &UnsafeMapIterator{
+		hiter:      mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)),
+		pKeyRType:  type2.pKeyRType,
+		pElemRType: type2.pElemRType,
+	}
+}
+
+type UnsafeMapIterator struct {
+	*hiter
+	pKeyRType  unsafe.Pointer
+	pElemRType unsafe.Pointer
+}
+
+func (iter *UnsafeMapIterator) HasNext() bool {
+	return iter.key != nil
+}
+
+func (iter *UnsafeMapIterator) Next() (interface{}, interface{}) {
+	key, elem := iter.UnsafeNext()
+	return packEFace(iter.pKeyRType, key), packEFace(iter.pElemRType, elem)
+}
+
+func (iter *UnsafeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) {
+	key := iter.key
+	elem := iter.value
+	mapiternext(iter.hiter)
+	return key, elem
+}

+ 46 - 0
vendor/github.com/modern-go/reflect2/unsafe_ptr.go

@@ -0,0 +1,46 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type UnsafePtrType struct {
+	unsafeType
+}
+
+func newUnsafePtrType(cfg *frozenConfig, type1 reflect.Type) *UnsafePtrType {
+	return &UnsafePtrType{
+		unsafeType: *newUnsafeType(cfg, type1),
+	}
+}
+
+func (type2 *UnsafePtrType) IsNil(obj interface{}) bool {
+	if obj == nil {
+		return true
+	}
+	objEFace := unpackEFace(obj)
+	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIsNil(objEFace.data)
+}
+
+func (type2 *UnsafePtrType) UnsafeIsNil(ptr unsafe.Pointer) bool {
+	if ptr == nil {
+		return true
+	}
+	return *(*unsafe.Pointer)(ptr) == nil
+}
+
+func (type2 *UnsafePtrType) LikePtr() bool {
+	return true
+}
+
+func (type2 *UnsafePtrType) Indirect(obj interface{}) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIndirect(objEFace.data)
+}
+
+func (type2 *UnsafePtrType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
+	return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr))
+}

+ 177 - 0
vendor/github.com/modern-go/reflect2/unsafe_slice.go

@@ -0,0 +1,177 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+// sliceHeader is a safe version of SliceHeader used within this package.
+type sliceHeader struct {
+	Data unsafe.Pointer
+	Len  int
+	Cap  int
+}
+
+type UnsafeSliceType struct {
+	unsafeType
+	elemRType  unsafe.Pointer
+	pElemRType unsafe.Pointer
+	elemSize   uintptr
+}
+
+func newUnsafeSliceType(cfg *frozenConfig, type1 reflect.Type) SliceType {
+	elemType := type1.Elem()
+	return &UnsafeSliceType{
+		unsafeType: *newUnsafeType(cfg, type1),
+		pElemRType: unpackEFace(reflect.PtrTo(elemType)).data,
+		elemRType:  unpackEFace(elemType).data,
+		elemSize:   elemType.Size(),
+	}
+}
+
+func (type2 *UnsafeSliceType) Set(obj interface{}, val interface{}) {
+	objEFace := unpackEFace(obj)
+	assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype)
+	valEFace := unpackEFace(val)
+	assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype)
+	type2.UnsafeSet(objEFace.data, valEFace.data)
+}
+
+func (type2 *UnsafeSliceType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) {
+	*(*sliceHeader)(ptr) = *(*sliceHeader)(val)
+}
+
+func (type2 *UnsafeSliceType) IsNil(obj interface{}) bool {
+	if obj == nil {
+		return true
+	}
+	objEFace := unpackEFace(obj)
+	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIsNil(objEFace.data)
+}
+
+func (type2 *UnsafeSliceType) UnsafeIsNil(ptr unsafe.Pointer) bool {
+	if ptr == nil {
+		return true
+	}
+	return (*sliceHeader)(ptr).Data == nil
+}
+
+func (type2 *UnsafeSliceType) SetNil(obj interface{}) {
+	objEFace := unpackEFace(obj)
+	assertType("SliceType.SetNil argument 1", type2.ptrRType, objEFace.rtype)
+	type2.UnsafeSetNil(objEFace.data)
+}
+
+func (type2 *UnsafeSliceType) UnsafeSetNil(ptr unsafe.Pointer) {
+	header := (*sliceHeader)(ptr)
+	header.Len = 0
+	header.Cap = 0
+	header.Data = nil
+}
+
+func (type2 *UnsafeSliceType) MakeSlice(length int, cap int) interface{} {
+	return packEFace(type2.ptrRType, type2.UnsafeMakeSlice(length, cap))
+}
+
+func (type2 *UnsafeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer {
+	header := &sliceHeader{unsafe_NewArray(type2.elemRType, cap), length, cap}
+	return unsafe.Pointer(header)
+}
+
+func (type2 *UnsafeSliceType) LengthOf(obj interface{}) int {
+	objEFace := unpackEFace(obj)
+	assertType("SliceType.Len argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeLengthOf(objEFace.data)
+}
+
+func (type2 *UnsafeSliceType) UnsafeLengthOf(obj unsafe.Pointer) int {
+	header := (*sliceHeader)(obj)
+	return header.Len
+}
+
+func (type2 *UnsafeSliceType) SetIndex(obj interface{}, index int, elem interface{}) {
+	objEFace := unpackEFace(obj)
+	assertType("SliceType.SetIndex argument 1", type2.ptrRType, objEFace.rtype)
+	elemEFace := unpackEFace(elem)
+	assertType("SliceType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype)
+	type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data)
+}
+
+func (type2 *UnsafeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) {
+	header := (*sliceHeader)(obj)
+	elemPtr := arrayAt(header.Data, index, type2.elemSize, "i < s.Len")
+	typedmemmove(type2.elemRType, elemPtr, elem)
+}
+
+func (type2 *UnsafeSliceType) GetIndex(obj interface{}, index int) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("SliceType.GetIndex argument 1", type2.ptrRType, objEFace.rtype)
+	elemPtr := type2.UnsafeGetIndex(objEFace.data, index)
+	return packEFace(type2.pElemRType, elemPtr)
+}
+
+func (type2 *UnsafeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer {
+	header := (*sliceHeader)(obj)
+	return arrayAt(header.Data, index, type2.elemSize, "i < s.Len")
+}
+
+func (type2 *UnsafeSliceType) Append(obj interface{}, elem interface{}) {
+	objEFace := unpackEFace(obj)
+	assertType("SliceType.Append argument 1", type2.ptrRType, objEFace.rtype)
+	elemEFace := unpackEFace(elem)
+	assertType("SliceType.Append argument 2", type2.pElemRType, elemEFace.rtype)
+	type2.UnsafeAppend(objEFace.data, elemEFace.data)
+}
+
+func (type2 *UnsafeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) {
+	header := (*sliceHeader)(obj)
+	oldLen := header.Len
+	type2.UnsafeGrow(obj, oldLen+1)
+	type2.UnsafeSetIndex(obj, oldLen, elem)
+}
+
+func (type2 *UnsafeSliceType) Cap(obj interface{}) int {
+	objEFace := unpackEFace(obj)
+	assertType("SliceType.Cap argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeCap(objEFace.data)
+}
+
+func (type2 *UnsafeSliceType) UnsafeCap(ptr unsafe.Pointer) int {
+	return (*sliceHeader)(ptr).Cap
+}
+
+func (type2 *UnsafeSliceType) Grow(obj interface{}, newLength int) {
+	objEFace := unpackEFace(obj)
+	assertType("SliceType.Grow argument 1", type2.ptrRType, objEFace.rtype)
+	type2.UnsafeGrow(objEFace.data, newLength)
+}
+
+func (type2 *UnsafeSliceType) UnsafeGrow(obj unsafe.Pointer, newLength int) {
+	header := (*sliceHeader)(obj)
+	if newLength <= header.Cap {
+		header.Len = newLength
+		return
+	}
+	newCap := calcNewCap(header.Cap, newLength)
+	newHeader := (*sliceHeader)(type2.UnsafeMakeSlice(header.Len, newCap))
+	typedslicecopy(type2.elemRType, *newHeader, *header)
+	header.Data = newHeader.Data
+	header.Cap = newHeader.Cap
+	header.Len = newLength
+}
+
+func calcNewCap(cap int, expectedCap int) int {
+	if cap == 0 {
+		cap = expectedCap
+	} else {
+		for cap < expectedCap {
+			if cap < 1024 {
+				cap += cap
+			} else {
+				cap += cap / 4
+			}
+		}
+	}
+	return cap
+}

+ 59 - 0
vendor/github.com/modern-go/reflect2/unsafe_struct.go

@@ -0,0 +1,59 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type UnsafeStructType struct {
+	unsafeType
+	likePtr bool
+}
+
+func newUnsafeStructType(cfg *frozenConfig, type1 reflect.Type) *UnsafeStructType {
+	return &UnsafeStructType{
+		unsafeType: *newUnsafeType(cfg, type1),
+		likePtr:    likePtrType(type1),
+	}
+}
+
+func (type2 *UnsafeStructType) LikePtr() bool {
+	return type2.likePtr
+}
+
+func (type2 *UnsafeStructType) Indirect(obj interface{}) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIndirect(objEFace.data)
+}
+
+func (type2 *UnsafeStructType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
+	if type2.likePtr {
+		return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr))
+	}
+	return packEFace(type2.rtype, ptr)
+}
+
+func (type2 *UnsafeStructType) FieldByName(name string) StructField {
+	structField, found := type2.Type.FieldByName(name)
+	if !found {
+		return nil
+	}
+	return newUnsafeStructField(type2, structField)
+}
+
+func (type2 *UnsafeStructType) Field(i int) StructField {
+	return newUnsafeStructField(type2, type2.Type.Field(i))
+}
+
+func (type2 *UnsafeStructType) FieldByIndex(index []int) StructField {
+	return newUnsafeStructField(type2, type2.Type.FieldByIndex(index))
+}
+
+func (type2 *UnsafeStructType) FieldByNameFunc(match func(string) bool) StructField {
+	structField, found := type2.Type.FieldByNameFunc(match)
+	if !found {
+		panic("field match condition not found in " + type2.Type.String())
+	}
+	return newUnsafeStructField(type2, structField)
+}

+ 85 - 0
vendor/github.com/modern-go/reflect2/unsafe_type.go

@@ -0,0 +1,85 @@
+package reflect2
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type unsafeType struct {
+	safeType
+	rtype    unsafe.Pointer
+	ptrRType unsafe.Pointer
+}
+
+func newUnsafeType(cfg *frozenConfig, type1 reflect.Type) *unsafeType {
+	return &unsafeType{
+		safeType: safeType{
+			Type: type1,
+			cfg:  cfg,
+		},
+		rtype:    unpackEFace(type1).data,
+		ptrRType: unpackEFace(reflect.PtrTo(type1)).data,
+	}
+}
+
+func (type2 *unsafeType) Set(obj interface{}, val interface{}) {
+	objEFace := unpackEFace(obj)
+	assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype)
+	valEFace := unpackEFace(val)
+	assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype)
+	type2.UnsafeSet(objEFace.data, valEFace.data)
+}
+
+func (type2 *unsafeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) {
+	typedmemmove(type2.rtype, ptr, val)
+}
+
+func (type2 *unsafeType) IsNil(obj interface{}) bool {
+	objEFace := unpackEFace(obj)
+	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIsNil(objEFace.data)
+}
+
+func (type2 *unsafeType) UnsafeIsNil(ptr unsafe.Pointer) bool {
+	return ptr == nil
+}
+
+func (type2 *unsafeType) UnsafeNew() unsafe.Pointer {
+	return unsafe_New(type2.rtype)
+}
+
+func (type2 *unsafeType) New() interface{} {
+	return packEFace(type2.ptrRType, type2.UnsafeNew())
+}
+
+func (type2 *unsafeType) PackEFace(ptr unsafe.Pointer) interface{} {
+	return packEFace(type2.ptrRType, ptr)
+}
+
+func (type2 *unsafeType) RType() uintptr {
+	return uintptr(type2.rtype)
+}
+
+func (type2 *unsafeType) Indirect(obj interface{}) interface{} {
+	objEFace := unpackEFace(obj)
+	assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype)
+	return type2.UnsafeIndirect(objEFace.data)
+}
+
+func (type2 *unsafeType) UnsafeIndirect(obj unsafe.Pointer) interface{} {
+	return packEFace(type2.rtype, obj)
+}
+
+func (type2 *unsafeType) LikePtr() bool {
+	return false
+}
+
+func assertType(where string, expectRType unsafe.Pointer, actualRType unsafe.Pointer) {
+	if expectRType != actualRType {
+		expectType := reflect.TypeOf(0)
+		(*iface)(unsafe.Pointer(&expectType)).data = expectRType
+		actualType := reflect.TypeOf(0)
+		(*iface)(unsafe.Pointer(&actualType)).data = actualRType
+		panic(where + ": expect " + expectType.String() + ", actual " + actualType.String())
+	}
+}

+ 0 - 227
vendor/github.com/ugorji/go/codec/0doc.go

@@ -1,227 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-/*
-Package codec provides a
-High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library
-for binc, msgpack, cbor, json.
-
-Supported Serialization formats are:
-
-  - msgpack: https://github.com/msgpack/msgpack
-  - binc:    http://github.com/ugorji/binc
-  - cbor:    http://cbor.io http://tools.ietf.org/html/rfc7049
-  - json:    http://json.org http://tools.ietf.org/html/rfc7159
-  - simple:
-
-To install:
-
-    go get github.com/ugorji/go/codec
-
-This package will carefully use 'unsafe' for performance reasons in specific places.
-You can build without unsafe use by passing the safe or appengine tag
-i.e. 'go install -tags=safe ...'. Note that unsafe is only supported for the last 3
-go sdk versions e.g. current go release is go 1.9, so we support unsafe use only from
-go 1.7+ . This is because supporting unsafe requires knowledge of implementation details.
-
-For detailed usage information, read the primer at http://ugorji.net/blog/go-codec-primer .
-
-The idiomatic Go support is as seen in other encoding packages in
-the standard library (ie json, xml, gob, etc).
-
-Rich Feature Set includes:
-
-  - Simple but extremely powerful and feature-rich API
-  - Support for go1.4 and above, while selectively using newer APIs for later releases
-  - Excellent code coverage ( > 90% )
-  - Very High Performance.
-    Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
-  - Careful selected use of 'unsafe' for targeted performance gains.
-    100% mode exists where 'unsafe' is not used at all.
-  - Lock-free (sans mutex) concurrency for scaling to 100's of cores
-  - In-place updates during decode, with option to zero value in maps and slices prior to decode
-  - Coerce types where appropriate
-    e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
-  - Corner Cases:
-    Overflows, nil maps/slices, nil values in streams are handled correctly
-  - Standard field renaming via tags
-  - Support for omitting empty fields during an encoding
-  - Encoding from any value and decoding into pointer to any value
-    (struct, slice, map, primitives, pointers, interface{}, etc)
-  - Extensions to support efficient encoding/decoding of any named types
-  - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
-  - Support IsZero() bool to determine if a value is a zero value.
-    Analogous to time.Time.IsZero() bool.
-  - Decoding without a schema (into a interface{}).
-    Includes Options to configure what specific map or slice type to use
-    when decoding an encoded list or map into a nil interface{}
-  - Mapping a non-interface type to an interface, so we can decode appropriately
-    into any interface type with a correctly configured non-interface value.
-  - Encode a struct as an array, and decode struct from an array in the data stream
-  - Option to encode struct keys as numbers (instead of strings)
-    (to support structured streams with fields encoded as numeric codes)
-  - Comprehensive support for anonymous fields
-  - Fast (no-reflection) encoding/decoding of common maps and slices
-  - Code-generation for faster performance.
-  - Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
-  - Support indefinite-length formats to enable true streaming
-    (for formats which support it e.g. json, cbor)
-  - Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes.
-    This mostly applies to maps, where iteration order is non-deterministic.
-  - NIL in data stream decoded as zero value
-  - Never silently skip data when decoding.
-    User decides whether to return an error or silently skip data when keys or indexes
-    in the data stream do not map to fields in the struct.
-  - Detect and error when encoding a cyclic reference (instead of stack overflow shutdown)
-  - Encode/Decode from/to chan types (for iterative streaming support)
-  - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
-  - Provides a RPC Server and Client Codec for net/rpc communication protocol.
-  - Handle unique idiosyncrasies of codecs e.g.
-    - For messagepack, configure how ambiguities in handling raw bytes are resolved
-    - For messagepack, provide rpc server/client codec to support
-      msgpack-rpc protocol defined at:
-      https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
-
-Extension Support
-
-Users can register a function to handle the encoding or decoding of
-their custom types.
-
-There are no restrictions on what the custom type can be. Some examples:
-
-    type BisSet   []int
-    type BitSet64 uint64
-    type UUID     string
-    type MyStructWithUnexportedFields struct { a int; b bool; c []int; }
-    type GifImage struct { ... }
-
-As an illustration, MyStructWithUnexportedFields would normally be
-encoded as an empty map because it has no exported fields, while UUID
-would be encoded as a string. However, with extension support, you can
-encode any of these however you like.
-
-Custom Encoding and Decoding
-
-This package maintains symmetry in the encoding and decoding halfs.
-We determine how to encode or decode by walking this decision tree
-
-  - is type a codec.Selfer?
-  - is there an extension registered for the type?
-  - is format binary, and is type a encoding.BinaryMarshaler and BinaryUnmarshaler?
-  - is format specifically json, and is type a encoding/json.Marshaler and Unmarshaler?
-  - is format text-based, and type an encoding.TextMarshaler?
-  - else we use a pair of functions based on the "kind" of the type e.g. map, slice, int64, etc
-
-This symmetry is important to reduce chances of issues happening because the
-encoding and decoding sides are out of sync e.g. decoded via very specific
-encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
-
-Consequently, if a type only defines one-half of the symmetry
-(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
-then that type doesn't satisfy the check and we will continue walking down the
-decision tree.
-
-RPC
-
-RPC Client and Server Codecs are implemented, so the codecs can be used
-with the standard net/rpc package.
-
-Usage
-
-The Handle is SAFE for concurrent READ, but NOT SAFE for concurrent modification.
-
-The Encoder and Decoder are NOT safe for concurrent use.
-
-Consequently, the usage model is basically:
-
-    - Create and initialize the Handle before any use.
-      Once created, DO NOT modify it.
-    - Multiple Encoders or Decoders can now use the Handle concurrently.
-      They only read information off the Handle (never write).
-    - However, each Encoder or Decoder MUST not be used concurrently
-    - To re-use an Encoder/Decoder, call Reset(...) on it first.
-      This allows you use state maintained on the Encoder/Decoder.
-
-Sample usage model:
-
-    // create and configure Handle
-    var (
-      bh codec.BincHandle
-      mh codec.MsgpackHandle
-      ch codec.CborHandle
-    )
-
-    mh.MapType = reflect.TypeOf(map[string]interface{}(nil))
-
-    // configure extensions
-    // e.g. for msgpack, define functions and enable Time support for tag 1
-    // mh.SetExt(reflect.TypeOf(time.Time{}), 1, myExt)
-
-    // create and use decoder/encoder
-    var (
-      r io.Reader
-      w io.Writer
-      b []byte
-      h = &bh // or mh to use msgpack
-    )
-
-    dec = codec.NewDecoder(r, h)
-    dec = codec.NewDecoderBytes(b, h)
-    err = dec.Decode(&v)
-
-    enc = codec.NewEncoder(w, h)
-    enc = codec.NewEncoderBytes(&b, h)
-    err = enc.Encode(v)
-
-    //RPC Server
-    go func() {
-        for {
-            conn, err := listener.Accept()
-            rpcCodec := codec.GoRpc.ServerCodec(conn, h)
-            //OR rpcCodec := codec.MsgpackSpecRpc.ServerCodec(conn, h)
-            rpc.ServeCodec(rpcCodec)
-        }
-    }()
-
-    //RPC Communication (client side)
-    conn, err = net.Dial("tcp", "localhost:5555")
-    rpcCodec := codec.GoRpc.ClientCodec(conn, h)
-    //OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
-    client := rpc.NewClientWithCodec(rpcCodec)
-
-Running Tests
-
-To run tests, use the following:
-
-    go test
-
-To run the full suite of tests, use the following:
-
-    go test -tags alltests -run Suite
-
-You can run the tag 'safe' to run tests or build in safe mode. e.g.
-
-    go test -tags safe -run Json
-    go test -tags "alltests safe" -run Suite
-
-Running Benchmarks
-
-Please see http://github.com/ugorji/go-codec-bench .
-
-Caveats
-
-Struct fields matching the following are ignored during encoding and decoding
-    - struct tag value set to -
-    - func, complex numbers, unsafe pointers
-    - unexported and not embedded
-    - unexported and embedded and not struct kind
-    - unexported and embedded pointers (from go1.10)
-
-Every other field in a struct will be encoded/decoded.
-
-Embedded fields are encoded as if they exist in the top-level struct,
-with some caveats. See Encode documentation.
-
-*/
-package codec
-

+ 0 - 1204
vendor/github.com/ugorji/go/codec/binc.go

@@ -1,1204 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"math"
-	"reflect"
-	"time"
-)
-
-const bincDoPrune = true // No longer needed. Needed before as C lib did not support pruning.
-
-// vd as low 4 bits (there are 16 slots)
-const (
-	bincVdSpecial byte = iota
-	bincVdPosInt
-	bincVdNegInt
-	bincVdFloat
-
-	bincVdString
-	bincVdByteArray
-	bincVdArray
-	bincVdMap
-
-	bincVdTimestamp
-	bincVdSmallInt
-	bincVdUnicodeOther
-	bincVdSymbol
-
-	bincVdDecimal
-	_               // open slot
-	_               // open slot
-	bincVdCustomExt = 0x0f
-)
-
-const (
-	bincSpNil byte = iota
-	bincSpFalse
-	bincSpTrue
-	bincSpNan
-	bincSpPosInf
-	bincSpNegInf
-	bincSpZeroFloat
-	bincSpZero
-	bincSpNegOne
-)
-
-const (
-	bincFlBin16 byte = iota
-	bincFlBin32
-	_ // bincFlBin32e
-	bincFlBin64
-	_ // bincFlBin64e
-	// others not currently supported
-)
-
-func bincdesc(vd, vs byte) string {
-	switch vd {
-	case bincVdSpecial:
-		switch vs {
-		case bincSpNil:
-			return "nil"
-		case bincSpFalse:
-			return "false"
-		case bincSpTrue:
-			return "true"
-		case bincSpNan, bincSpPosInf, bincSpNegInf, bincSpZeroFloat:
-			return "float"
-		case bincSpZero:
-			return "uint"
-		case bincSpNegOne:
-			return "int"
-		default:
-			return "unknown"
-		}
-	case bincVdSmallInt, bincVdPosInt:
-		return "uint"
-	case bincVdNegInt:
-		return "int"
-	case bincVdFloat:
-		return "float"
-	case bincVdSymbol:
-		return "string"
-	case bincVdString:
-		return "string"
-	case bincVdByteArray:
-		return "bytes"
-	case bincVdTimestamp:
-		return "time"
-	case bincVdCustomExt:
-		return "ext"
-	case bincVdArray:
-		return "array"
-	case bincVdMap:
-		return "map"
-	default:
-		return "unknown"
-	}
-}
-
-type bincEncDriver struct {
-	e *Encoder
-	h *BincHandle
-	w *encWriterSwitch
-	m map[string]uint16 // symbols
-	b [16]byte          // scratch, used for encoding numbers - bigendian style
-	s uint16            // symbols sequencer
-	// c containerState
-	encDriverTrackContainerWriter
-	noBuiltInTypes
-	// encNoSeparator
-	_ [1]uint64 // padding
-}
-
-func (e *bincEncDriver) EncodeNil() {
-	e.w.writen1(bincVdSpecial<<4 | bincSpNil)
-}
-
-func (e *bincEncDriver) EncodeTime(t time.Time) {
-	if t.IsZero() {
-		e.EncodeNil()
-	} else {
-		bs := bincEncodeTime(t)
-		e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
-		e.w.writeb(bs)
-	}
-}
-
-func (e *bincEncDriver) EncodeBool(b bool) {
-	if b {
-		e.w.writen1(bincVdSpecial<<4 | bincSpTrue)
-	} else {
-		e.w.writen1(bincVdSpecial<<4 | bincSpFalse)
-	}
-}
-
-func (e *bincEncDriver) EncodeFloat32(f float32) {
-	if f == 0 {
-		e.w.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
-		return
-	}
-	e.w.writen1(bincVdFloat<<4 | bincFlBin32)
-	bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f))
-}
-
-func (e *bincEncDriver) EncodeFloat64(f float64) {
-	if f == 0 {
-		e.w.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
-		return
-	}
-	bigen.PutUint64(e.b[:8], math.Float64bits(f))
-	if bincDoPrune {
-		i := 7
-		for ; i >= 0 && (e.b[i] == 0); i-- {
-		}
-		i++
-		if i <= 6 {
-			e.w.writen1(bincVdFloat<<4 | 0x8 | bincFlBin64)
-			e.w.writen1(byte(i))
-			e.w.writeb(e.b[:i])
-			return
-		}
-	}
-	e.w.writen1(bincVdFloat<<4 | bincFlBin64)
-	e.w.writeb(e.b[:8])
-}
-
-func (e *bincEncDriver) encIntegerPrune(bd byte, pos bool, v uint64, lim uint8) {
-	if lim == 4 {
-		bigen.PutUint32(e.b[:lim], uint32(v))
-	} else {
-		bigen.PutUint64(e.b[:lim], v)
-	}
-	if bincDoPrune {
-		i := pruneSignExt(e.b[:lim], pos)
-		e.w.writen1(bd | lim - 1 - byte(i))
-		e.w.writeb(e.b[i:lim])
-	} else {
-		e.w.writen1(bd | lim - 1)
-		e.w.writeb(e.b[:lim])
-	}
-}
-
-func (e *bincEncDriver) EncodeInt(v int64) {
-	// const nbd byte = bincVdNegInt << 4
-	if v >= 0 {
-		e.encUint(bincVdPosInt<<4, true, uint64(v))
-	} else if v == -1 {
-		e.w.writen1(bincVdSpecial<<4 | bincSpNegOne)
-	} else {
-		e.encUint(bincVdNegInt<<4, false, uint64(-v))
-	}
-}
-
-func (e *bincEncDriver) EncodeUint(v uint64) {
-	e.encUint(bincVdPosInt<<4, true, v)
-}
-
-func (e *bincEncDriver) encUint(bd byte, pos bool, v uint64) {
-	if v == 0 {
-		e.w.writen1(bincVdSpecial<<4 | bincSpZero)
-	} else if pos && v >= 1 && v <= 16 {
-		e.w.writen1(bincVdSmallInt<<4 | byte(v-1))
-	} else if v <= math.MaxUint8 {
-		e.w.writen2(bd|0x0, byte(v))
-	} else if v <= math.MaxUint16 {
-		e.w.writen1(bd | 0x01)
-		bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v))
-	} else if v <= math.MaxUint32 {
-		e.encIntegerPrune(bd, pos, v, 4)
-	} else {
-		e.encIntegerPrune(bd, pos, v, 8)
-	}
-}
-
-func (e *bincEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, _ *Encoder) {
-	bs := ext.WriteExt(rv)
-	if bs == nil {
-		e.EncodeNil()
-		return
-	}
-	e.encodeExtPreamble(uint8(xtag), len(bs))
-	e.w.writeb(bs)
-}
-
-func (e *bincEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) {
-	e.encodeExtPreamble(uint8(re.Tag), len(re.Data))
-	e.w.writeb(re.Data)
-}
-
-func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) {
-	e.encLen(bincVdCustomExt<<4, uint64(length))
-	e.w.writen1(xtag)
-}
-
-func (e *bincEncDriver) WriteArrayStart(length int) {
-	e.encLen(bincVdArray<<4, uint64(length))
-	e.c = containerArrayStart
-}
-
-func (e *bincEncDriver) WriteMapStart(length int) {
-	e.encLen(bincVdMap<<4, uint64(length))
-	e.c = containerMapStart
-}
-
-func (e *bincEncDriver) EncodeSymbol(v string) {
-	// if WriteSymbolsNoRefs {
-	// 	e.encodeString(cUTF8, v)
-	// 	return
-	// }
-
-	//symbols only offer benefit when string length > 1.
-	//This is because strings with length 1 take only 2 bytes to store
-	//(bd with embedded length, and single byte for string val).
-
-	l := len(v)
-	if l == 0 {
-		e.encBytesLen(cUTF8, 0)
-		return
-	} else if l == 1 {
-		e.encBytesLen(cUTF8, 1)
-		e.w.writen1(v[0])
-		return
-	}
-	if e.m == nil {
-		e.m = make(map[string]uint16, 16)
-	}
-	ui, ok := e.m[v]
-	if ok {
-		if ui <= math.MaxUint8 {
-			e.w.writen2(bincVdSymbol<<4, byte(ui))
-		} else {
-			e.w.writen1(bincVdSymbol<<4 | 0x8)
-			bigenHelper{e.b[:2], e.w}.writeUint16(ui)
-		}
-	} else {
-		e.s++
-		ui = e.s
-		//ui = uint16(atomic.AddUint32(&e.s, 1))
-		e.m[v] = ui
-		var lenprec uint8
-		if l <= math.MaxUint8 {
-			// lenprec = 0
-		} else if l <= math.MaxUint16 {
-			lenprec = 1
-		} else if int64(l) <= math.MaxUint32 {
-			lenprec = 2
-		} else {
-			lenprec = 3
-		}
-		if ui <= math.MaxUint8 {
-			e.w.writen2(bincVdSymbol<<4|0x0|0x4|lenprec, byte(ui))
-		} else {
-			e.w.writen1(bincVdSymbol<<4 | 0x8 | 0x4 | lenprec)
-			bigenHelper{e.b[:2], e.w}.writeUint16(ui)
-		}
-		if lenprec == 0 {
-			e.w.writen1(byte(l))
-		} else if lenprec == 1 {
-			bigenHelper{e.b[:2], e.w}.writeUint16(uint16(l))
-		} else if lenprec == 2 {
-			bigenHelper{e.b[:4], e.w}.writeUint32(uint32(l))
-		} else {
-			bigenHelper{e.b[:8], e.w}.writeUint64(uint64(l))
-		}
-		e.w.writestr(v)
-	}
-}
-
-func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
-	if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
-		e.EncodeSymbol(v)
-		return
-	}
-	l := uint64(len(v))
-	e.encBytesLen(c, l)
-	if l > 0 {
-		e.w.writestr(v)
-	}
-}
-
-func (e *bincEncDriver) EncodeStringEnc(c charEncoding, v string) {
-	if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
-		e.EncodeSymbol(v)
-		return
-	}
-	l := uint64(len(v))
-	e.encLen(bincVdString<<4, l) // e.encBytesLen(c, l)
-	if l > 0 {
-		e.w.writestr(v)
-	}
-
-}
-
-func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
-	if v == nil {
-		e.EncodeNil()
-		return
-	}
-	l := uint64(len(v))
-	e.encBytesLen(c, l)
-	if l > 0 {
-		e.w.writeb(v)
-	}
-}
-
-func (e *bincEncDriver) EncodeStringBytesRaw(v []byte) {
-	if v == nil {
-		e.EncodeNil()
-		return
-	}
-	l := uint64(len(v))
-	e.encLen(bincVdByteArray<<4, l) // e.encBytesLen(c, l)
-	if l > 0 {
-		e.w.writeb(v)
-	}
-}
-
-func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
-	//TODO: support bincUnicodeOther (for now, just use string or bytearray)
-	if c == cRAW {
-		e.encLen(bincVdByteArray<<4, length)
-	} else {
-		e.encLen(bincVdString<<4, length)
-	}
-}
-
-func (e *bincEncDriver) encLen(bd byte, l uint64) {
-	if l < 12 {
-		e.w.writen1(bd | uint8(l+4))
-	} else {
-		e.encLenNumber(bd, l)
-	}
-}
-
-func (e *bincEncDriver) encLenNumber(bd byte, v uint64) {
-	if v <= math.MaxUint8 {
-		e.w.writen2(bd, byte(v))
-	} else if v <= math.MaxUint16 {
-		e.w.writen1(bd | 0x01)
-		bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v))
-	} else if v <= math.MaxUint32 {
-		e.w.writen1(bd | 0x02)
-		bigenHelper{e.b[:4], e.w}.writeUint32(uint32(v))
-	} else {
-		e.w.writen1(bd | 0x03)
-		bigenHelper{e.b[:8], e.w}.writeUint64(uint64(v))
-	}
-}
-
-//------------------------------------
-
-type bincDecSymbol struct {
-	s string
-	b []byte
-	i uint16
-}
-
-type bincDecDriver struct {
-	decDriverNoopContainerReader
-	noBuiltInTypes
-
-	d      *Decoder
-	h      *BincHandle
-	r      *decReaderSwitch
-	br     bool // bytes reader
-	bdRead bool
-	bd     byte
-	vd     byte
-	vs     byte
-	_      [3]byte // padding
-	// linear searching on this slice is ok,
-	// because we typically expect < 32 symbols in each stream.
-	s []bincDecSymbol
-
-	// noStreamingCodec
-	// decNoSeparator
-
-	b [(8 + 1) * 8]byte // scratch
-}
-
-func (d *bincDecDriver) readNextBd() {
-	d.bd = d.r.readn1()
-	d.vd = d.bd >> 4
-	d.vs = d.bd & 0x0f
-	d.bdRead = true
-}
-
-func (d *bincDecDriver) uncacheRead() {
-	if d.bdRead {
-		d.r.unreadn1()
-		d.bdRead = false
-	}
-}
-
-func (d *bincDecDriver) ContainerType() (vt valueType) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.vd == bincVdSpecial && d.vs == bincSpNil {
-		return valueTypeNil
-	} else if d.vd == bincVdByteArray {
-		return valueTypeBytes
-	} else if d.vd == bincVdString {
-		return valueTypeString
-	} else if d.vd == bincVdArray {
-		return valueTypeArray
-	} else if d.vd == bincVdMap {
-		return valueTypeMap
-	}
-	// else {
-	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
-	// }
-	return valueTypeUnset
-}
-
-func (d *bincDecDriver) TryDecodeAsNil() bool {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == bincVdSpecial<<4|bincSpNil {
-		d.bdRead = false
-		return true
-	}
-	return false
-}
-
-func (d *bincDecDriver) DecodeTime() (t time.Time) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == bincVdSpecial<<4|bincSpNil {
-		d.bdRead = false
-		return
-	}
-	if d.vd != bincVdTimestamp {
-		d.d.errorf("cannot decode time - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	t, err := bincDecodeTime(d.r.readx(uint(d.vs)))
-	if err != nil {
-		panic(err)
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
-	if vs&0x8 == 0 {
-		d.r.readb(d.b[0:defaultLen])
-	} else {
-		l := d.r.readn1()
-		if l > 8 {
-			d.d.errorf("cannot read float - at most 8 bytes used to represent float - received %v bytes", l)
-			return
-		}
-		for i := l; i < 8; i++ {
-			d.b[i] = 0
-		}
-		d.r.readb(d.b[0:l])
-	}
-}
-
-func (d *bincDecDriver) decFloat() (f float64) {
-	//if true { f = math.Float64frombits(bigen.Uint64(d.r.readx(8))); break; }
-	if x := d.vs & 0x7; x == bincFlBin32 {
-		d.decFloatPre(d.vs, 4)
-		f = float64(math.Float32frombits(bigen.Uint32(d.b[0:4])))
-	} else if x == bincFlBin64 {
-		d.decFloatPre(d.vs, 8)
-		f = math.Float64frombits(bigen.Uint64(d.b[0:8]))
-	} else {
-		d.d.errorf("read float - only float32 and float64 are supported - %s %x-%x/%s",
-			msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	return
-}
-
-func (d *bincDecDriver) decUint() (v uint64) {
-	// need to inline the code (interface conversion and type assertion expensive)
-	switch d.vs {
-	case 0:
-		v = uint64(d.r.readn1())
-	case 1:
-		d.r.readb(d.b[6:8])
-		v = uint64(bigen.Uint16(d.b[6:8]))
-	case 2:
-		d.b[4] = 0
-		d.r.readb(d.b[5:8])
-		v = uint64(bigen.Uint32(d.b[4:8]))
-	case 3:
-		d.r.readb(d.b[4:8])
-		v = uint64(bigen.Uint32(d.b[4:8]))
-	case 4, 5, 6:
-		lim := 7 - d.vs
-		d.r.readb(d.b[lim:8])
-		for i := uint8(0); i < lim; i++ {
-			d.b[i] = 0
-		}
-		v = uint64(bigen.Uint64(d.b[:8]))
-	case 7:
-		d.r.readb(d.b[:8])
-		v = uint64(bigen.Uint64(d.b[:8]))
-	default:
-		d.d.errorf("unsigned integers with greater than 64 bits of precision not supported")
-		return
-	}
-	return
-}
-
-func (d *bincDecDriver) decCheckInteger() (ui uint64, neg bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	vd, vs := d.vd, d.vs
-	if vd == bincVdPosInt {
-		ui = d.decUint()
-	} else if vd == bincVdNegInt {
-		ui = d.decUint()
-		neg = true
-	} else if vd == bincVdSmallInt {
-		ui = uint64(d.vs) + 1
-	} else if vd == bincVdSpecial {
-		if vs == bincSpZero {
-			//i = 0
-		} else if vs == bincSpNegOne {
-			neg = true
-			ui = 1
-		} else {
-			d.d.errorf("integer decode fails - invalid special value from descriptor %x-%x/%s",
-				d.vd, d.vs, bincdesc(d.vd, d.vs))
-			return
-		}
-	} else {
-		d.d.errorf("integer can only be decoded from int/uint. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
-		return
-	}
-	return
-}
-
-func (d *bincDecDriver) DecodeInt64() (i int64) {
-	ui, neg := d.decCheckInteger()
-	i = chkOvf.SignedIntV(ui)
-	if neg {
-		i = -i
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) DecodeUint64() (ui uint64) {
-	ui, neg := d.decCheckInteger()
-	if neg {
-		d.d.errorf("assigning negative signed value to unsigned integer type")
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) DecodeFloat64() (f float64) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	vd, vs := d.vd, d.vs
-	if vd == bincVdSpecial {
-		d.bdRead = false
-		if vs == bincSpNan {
-			return math.NaN()
-		} else if vs == bincSpPosInf {
-			return math.Inf(1)
-		} else if vs == bincSpZeroFloat || vs == bincSpZero {
-			return
-		} else if vs == bincSpNegInf {
-			return math.Inf(-1)
-		} else {
-			d.d.errorf("float - invalid special value from descriptor %x-%x/%s",
-				d.vd, d.vs, bincdesc(d.vd, d.vs))
-			return
-		}
-	} else if vd == bincVdFloat {
-		f = d.decFloat()
-	} else {
-		f = float64(d.DecodeInt64())
-	}
-	d.bdRead = false
-	return
-}
-
-// bool can be decoded from bool only (single byte).
-func (d *bincDecDriver) DecodeBool() (b bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if bd := d.bd; bd == (bincVdSpecial | bincSpFalse) {
-		// b = false
-	} else if bd == (bincVdSpecial | bincSpTrue) {
-		b = true
-	} else {
-		d.d.errorf("bool - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) ReadMapStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.vd != bincVdMap {
-		d.d.errorf("map - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	length = d.decLen()
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) ReadArrayStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.vd != bincVdArray {
-		d.d.errorf("array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	length = d.decLen()
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) decLen() int {
-	if d.vs > 3 {
-		return int(d.vs - 4)
-	}
-	return int(d.decLenNumber())
-}
-
-func (d *bincDecDriver) decLenNumber() (v uint64) {
-	if x := d.vs; x == 0 {
-		v = uint64(d.r.readn1())
-	} else if x == 1 {
-		d.r.readb(d.b[6:8])
-		v = uint64(bigen.Uint16(d.b[6:8]))
-	} else if x == 2 {
-		d.r.readb(d.b[4:8])
-		v = uint64(bigen.Uint32(d.b[4:8]))
-	} else {
-		d.r.readb(d.b[:8])
-		v = bigen.Uint64(d.b[:8])
-	}
-	return
-}
-
-func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (
-	bs2 []byte, s string) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == bincVdSpecial<<4|bincSpNil {
-		d.bdRead = false
-		return
-	}
-	var slen = -1
-	// var ok bool
-	switch d.vd {
-	case bincVdString, bincVdByteArray:
-		slen = d.decLen()
-		if zerocopy {
-			if d.br {
-				bs2 = d.r.readx(uint(slen))
-			} else if len(bs) == 0 {
-				bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, d.b[:])
-			} else {
-				bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, bs)
-			}
-		} else {
-			bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, bs)
-		}
-		if withString {
-			s = string(bs2)
-		}
-	case bincVdSymbol:
-		// zerocopy doesn't apply for symbols,
-		// as the values must be stored in a table for later use.
-		//
-		//from vs: extract numSymbolBytes, containsStringVal, strLenPrecision,
-		//extract symbol
-		//if containsStringVal, read it and put in map
-		//else look in map for string value
-		var symbol uint16
-		vs := d.vs
-		if vs&0x8 == 0 {
-			symbol = uint16(d.r.readn1())
-		} else {
-			symbol = uint16(bigen.Uint16(d.r.readx(2)))
-		}
-		if d.s == nil {
-			d.s = make([]bincDecSymbol, 0, 16)
-		}
-
-		if vs&0x4 == 0 {
-			for i := range d.s {
-				j := &d.s[i]
-				if j.i == symbol {
-					bs2 = j.b
-					if withString {
-						if j.s == "" && bs2 != nil {
-							j.s = string(bs2)
-						}
-						s = j.s
-					}
-					break
-				}
-			}
-		} else {
-			switch vs & 0x3 {
-			case 0:
-				slen = int(d.r.readn1())
-			case 1:
-				slen = int(bigen.Uint16(d.r.readx(2)))
-			case 2:
-				slen = int(bigen.Uint32(d.r.readx(4)))
-			case 3:
-				slen = int(bigen.Uint64(d.r.readx(8)))
-			}
-			// since using symbols, do not store any part of
-			// the parameter bs in the map, as it might be a shared buffer.
-			// bs2 = decByteSlice(d.r, slen, bs)
-			bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, nil)
-			if withString {
-				s = string(bs2)
-			}
-			d.s = append(d.s, bincDecSymbol{i: symbol, s: s, b: bs2})
-		}
-	default:
-		d.d.errorf("string/bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) DecodeString() (s string) {
-	// DecodeBytes does not accommodate symbols, whose impl stores string version in map.
-	// Use decStringAndBytes directly.
-	// return string(d.DecodeBytes(d.b[:], true, true))
-	_, s = d.decStringAndBytes(d.b[:], true, true)
-	return
-}
-
-func (d *bincDecDriver) DecodeStringAsBytes() (s []byte) {
-	s, _ = d.decStringAndBytes(d.b[:], false, true)
-	return
-}
-
-func (d *bincDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == bincVdSpecial<<4|bincSpNil {
-		d.bdRead = false
-		return nil
-	}
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	if d.vd == bincVdArray {
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	}
-	var clen int
-	if d.vd == bincVdString || d.vd == bincVdByteArray {
-		clen = d.decLen()
-	} else {
-		d.d.errorf("bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	d.bdRead = false
-	if zerocopy {
-		if d.br {
-			return d.r.readx(uint(clen))
-		} else if len(bs) == 0 {
-			bs = d.b[:]
-		}
-	}
-	return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
-}
-
-func (d *bincDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
-	if xtag > 0xff {
-		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
-		return
-	}
-	realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
-	realxtag = uint64(realxtag1)
-	if ext == nil {
-		re := rv.(*RawExt)
-		re.Tag = realxtag
-		re.Data = detachZeroCopyBytes(d.br, re.Data, xbs)
-	} else {
-		ext.ReadExt(rv, xbs)
-	}
-	return
-}
-
-func (d *bincDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.vd == bincVdCustomExt {
-		l := d.decLen()
-		xtag = d.r.readn1()
-		if verifyTag && xtag != tag {
-			d.d.errorf("wrong extension tag - got %b, expecting: %v", xtag, tag)
-			return
-		}
-		if d.br {
-			xbs = d.r.readx(uint(l))
-		} else {
-			xbs = decByteSlice(d.r, l, d.d.h.MaxInitLen, d.d.b[:])
-		}
-	} else if d.vd == bincVdByteArray {
-		xbs = d.DecodeBytes(nil, true)
-	} else {
-		d.d.errorf("ext - expecting extensions or byte array - %s %x-%x/%s",
-			msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) DecodeNaked() {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-
-	n := d.d.naked()
-	var decodeFurther bool
-
-	switch d.vd {
-	case bincVdSpecial:
-		switch d.vs {
-		case bincSpNil:
-			n.v = valueTypeNil
-		case bincSpFalse:
-			n.v = valueTypeBool
-			n.b = false
-		case bincSpTrue:
-			n.v = valueTypeBool
-			n.b = true
-		case bincSpNan:
-			n.v = valueTypeFloat
-			n.f = math.NaN()
-		case bincSpPosInf:
-			n.v = valueTypeFloat
-			n.f = math.Inf(1)
-		case bincSpNegInf:
-			n.v = valueTypeFloat
-			n.f = math.Inf(-1)
-		case bincSpZeroFloat:
-			n.v = valueTypeFloat
-			n.f = float64(0)
-		case bincSpZero:
-			n.v = valueTypeUint
-			n.u = uint64(0) // int8(0)
-		case bincSpNegOne:
-			n.v = valueTypeInt
-			n.i = int64(-1) // int8(-1)
-		default:
-			d.d.errorf("cannot infer value - unrecognized special value from descriptor %x-%x/%s",
-				d.vd, d.vs, bincdesc(d.vd, d.vs))
-		}
-	case bincVdSmallInt:
-		n.v = valueTypeUint
-		n.u = uint64(int8(d.vs)) + 1 // int8(d.vs) + 1
-	case bincVdPosInt:
-		n.v = valueTypeUint
-		n.u = d.decUint()
-	case bincVdNegInt:
-		n.v = valueTypeInt
-		n.i = -(int64(d.decUint()))
-	case bincVdFloat:
-		n.v = valueTypeFloat
-		n.f = d.decFloat()
-	case bincVdSymbol:
-		n.v = valueTypeSymbol
-		n.s = d.DecodeString()
-	case bincVdString:
-		n.v = valueTypeString
-		n.s = d.DecodeString()
-	case bincVdByteArray:
-		n.v = valueTypeBytes
-		n.l = d.DecodeBytes(nil, false)
-	case bincVdTimestamp:
-		n.v = valueTypeTime
-		tt, err := bincDecodeTime(d.r.readx(uint(d.vs)))
-		if err != nil {
-			panic(err)
-		}
-		n.t = tt
-	case bincVdCustomExt:
-		n.v = valueTypeExt
-		l := d.decLen()
-		n.u = uint64(d.r.readn1())
-		if d.br {
-			n.l = d.r.readx(uint(l))
-		} else {
-			n.l = decByteSlice(d.r, l, d.d.h.MaxInitLen, d.d.b[:])
-		}
-	case bincVdArray:
-		n.v = valueTypeArray
-		decodeFurther = true
-	case bincVdMap:
-		n.v = valueTypeMap
-		decodeFurther = true
-	default:
-		d.d.errorf("cannot infer value - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-	}
-
-	if !decodeFurther {
-		d.bdRead = false
-	}
-	if n.v == valueTypeUint && d.h.SignedInteger {
-		n.v = valueTypeInt
-		n.i = int64(n.u)
-	}
-}
-
-//------------------------------------
-
-//BincHandle is a Handle for the Binc Schema-Free Encoding Format
-//defined at https://github.com/ugorji/binc .
-//
-//BincHandle currently supports all Binc features with the following EXCEPTIONS:
-//  - only integers up to 64 bits of precision are supported.
-//    big integers are unsupported.
-//  - Only IEEE 754 binary32 and binary64 floats are supported (ie Go float32 and float64 types).
-//    extended precision and decimal IEEE 754 floats are unsupported.
-//  - Only UTF-8 strings supported.
-//    Unicode_Other Binc types (UTF16, UTF32) are currently unsupported.
-//
-//Note that these EXCEPTIONS are temporary and full support is possible and may happen soon.
-type BincHandle struct {
-	BasicHandle
-	binaryEncodingType
-	noElemSeparators
-
-	// AsSymbols defines what should be encoded as symbols.
-	//
-	// Encoding as symbols can reduce the encoded size significantly.
-	//
-	// However, during decoding, each string to be encoded as a symbol must
-	// be checked to see if it has been seen before. Consequently, encoding time
-	// will increase if using symbols, because string comparisons has a clear cost.
-	//
-	// Values:
-	// - 0: default: library uses best judgement
-	// - 1: use symbols
-	// - 2: do not use symbols
-	AsSymbols uint8
-
-	// AsSymbols: may later on introduce more options ...
-	// - m: map keys
-	// - s: struct fields
-	// - n: none
-	// - a: all: same as m, s, ...
-
-	// _ [1]uint64 // padding
-}
-
-// Name returns the name of the handle: binc
-func (h *BincHandle) Name() string { return "binc" }
-
-// SetBytesExt sets an extension
-func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
-}
-
-func (h *BincHandle) newEncDriver(e *Encoder) encDriver {
-	return &bincEncDriver{e: e, h: h, w: e.w}
-}
-
-func (h *BincHandle) newDecDriver(d *Decoder) decDriver {
-	return &bincDecDriver{d: d, h: h, r: d.r, br: d.bytes}
-}
-
-func (e *bincEncDriver) reset() {
-	e.w = e.e.w
-	e.s = 0
-	e.c = 0
-	e.m = nil
-}
-
-func (d *bincDecDriver) reset() {
-	d.r, d.br = d.d.r, d.d.bytes
-	d.s = nil
-	d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0
-}
-
-// var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
-
-// EncodeTime encodes a time.Time as a []byte, including
-// information on the instant in time and UTC offset.
-//
-// Format Description
-//
-//   A timestamp is composed of 3 components:
-//
-//   - secs: signed integer representing seconds since unix epoch
-//   - nsces: unsigned integer representing fractional seconds as a
-//     nanosecond offset within secs, in the range 0 <= nsecs < 1e9
-//   - tz: signed integer representing timezone offset in minutes east of UTC,
-//     and a dst (daylight savings time) flag
-//
-//   When encoding a timestamp, the first byte is the descriptor, which
-//   defines which components are encoded and how many bytes are used to
-//   encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
-//   is not encoded in the byte array explicitly*.
-//
-//       Descriptor 8 bits are of the form `A B C DDD EE`:
-//           A:   Is secs component encoded? 1 = true
-//           B:   Is nsecs component encoded? 1 = true
-//           C:   Is tz component encoded? 1 = true
-//           DDD: Number of extra bytes for secs (range 0-7).
-//                If A = 1, secs encoded in DDD+1 bytes.
-//                    If A = 0, secs is not encoded, and is assumed to be 0.
-//                    If A = 1, then we need at least 1 byte to encode secs.
-//                    DDD says the number of extra bytes beyond that 1.
-//                    E.g. if DDD=0, then secs is represented in 1 byte.
-//                         if DDD=2, then secs is represented in 3 bytes.
-//           EE:  Number of extra bytes for nsecs (range 0-3).
-//                If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
-//
-//   Following the descriptor bytes, subsequent bytes are:
-//
-//       secs component encoded in `DDD + 1` bytes (if A == 1)
-//       nsecs component encoded in `EE + 1` bytes (if B == 1)
-//       tz component encoded in 2 bytes (if C == 1)
-//
-//   secs and nsecs components are integers encoded in a BigEndian
-//   2-complement encoding format.
-//
-//   tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
-//   Least significant bit 0 are described below:
-//
-//       Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
-//       Bit 15 = have\_dst: set to 1 if we set the dst flag.
-//       Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
-//       Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
-//
-func bincEncodeTime(t time.Time) []byte {
-	//t := rv.Interface().(time.Time)
-	tsecs, tnsecs := t.Unix(), t.Nanosecond()
-	var (
-		bd   byte
-		btmp [8]byte
-		bs   [16]byte
-		i    int = 1
-	)
-	l := t.Location()
-	if l == time.UTC {
-		l = nil
-	}
-	if tsecs != 0 {
-		bd = bd | 0x80
-		bigen.PutUint64(btmp[:], uint64(tsecs))
-		f := pruneSignExt(btmp[:], tsecs >= 0)
-		bd = bd | (byte(7-f) << 2)
-		copy(bs[i:], btmp[f:])
-		i = i + (8 - f)
-	}
-	if tnsecs != 0 {
-		bd = bd | 0x40
-		bigen.PutUint32(btmp[:4], uint32(tnsecs))
-		f := pruneSignExt(btmp[:4], true)
-		bd = bd | byte(3-f)
-		copy(bs[i:], btmp[f:4])
-		i = i + (4 - f)
-	}
-	if l != nil {
-		bd = bd | 0x20
-		// Note that Go Libs do not give access to dst flag.
-		_, zoneOffset := t.Zone()
-		//zoneName, zoneOffset := t.Zone()
-		zoneOffset /= 60
-		z := uint16(zoneOffset)
-		bigen.PutUint16(btmp[:2], z)
-		// clear dst flags
-		bs[i] = btmp[0] & 0x3f
-		bs[i+1] = btmp[1]
-		i = i + 2
-	}
-	bs[0] = bd
-	return bs[0:i]
-}
-
-// bincDecodeTime decodes a []byte into a time.Time.
-func bincDecodeTime(bs []byte) (tt time.Time, err error) {
-	bd := bs[0]
-	var (
-		tsec  int64
-		tnsec uint32
-		tz    uint16
-		i     byte = 1
-		i2    byte
-		n     byte
-	)
-	if bd&(1<<7) != 0 {
-		var btmp [8]byte
-		n = ((bd >> 2) & 0x7) + 1
-		i2 = i + n
-		copy(btmp[8-n:], bs[i:i2])
-		//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
-		if bs[i]&(1<<7) != 0 {
-			copy(btmp[0:8-n], bsAll0xff)
-			//for j,k := byte(0), 8-n; j < k; j++ {	btmp[j] = 0xff }
-		}
-		i = i2
-		tsec = int64(bigen.Uint64(btmp[:]))
-	}
-	if bd&(1<<6) != 0 {
-		var btmp [4]byte
-		n = (bd & 0x3) + 1
-		i2 = i + n
-		copy(btmp[4-n:], bs[i:i2])
-		i = i2
-		tnsec = bigen.Uint32(btmp[:])
-	}
-	if bd&(1<<5) == 0 {
-		tt = time.Unix(tsec, int64(tnsec)).UTC()
-		return
-	}
-	// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
-	// However, we need name here, so it can be shown when time is printed.
-	// Zone name is in form: UTC-08:00.
-	// Note that Go Libs do not give access to dst flag, so we ignore dst bits
-
-	i2 = i + 2
-	tz = bigen.Uint16(bs[i:i2])
-	// i = i2
-	// sign extend sign bit into top 2 MSB (which were dst bits):
-	if tz&(1<<13) == 0 { // positive
-		tz = tz & 0x3fff //clear 2 MSBs: dst bits
-	} else { // negative
-		tz = tz | 0xc000 //set 2 MSBs: dst bits
-	}
-	tzint := int16(tz)
-	if tzint == 0 {
-		tt = time.Unix(tsec, int64(tnsec)).UTC()
-	} else {
-		// For Go Time, do not use a descriptive timezone.
-		// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
-		// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
-		// var zoneName = timeLocUTCName(tzint)
-		tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
-	}
-	return
-}
-
-var _ decDriver = (*bincDecDriver)(nil)
-var _ encDriver = (*bincEncDriver)(nil)

+ 0 - 769
vendor/github.com/ugorji/go/codec/cbor.go

@@ -1,769 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"math"
-	"reflect"
-	"time"
-)
-
-const (
-	cborMajorUint byte = iota
-	cborMajorNegInt
-	cborMajorBytes
-	cborMajorText
-	cborMajorArray
-	cborMajorMap
-	cborMajorTag
-	cborMajorOther
-)
-
-const (
-	cborBdFalse byte = 0xf4 + iota
-	cborBdTrue
-	cborBdNil
-	cborBdUndefined
-	cborBdExt
-	cborBdFloat16
-	cborBdFloat32
-	cborBdFloat64
-)
-
-const (
-	cborBdIndefiniteBytes  byte = 0x5f
-	cborBdIndefiniteString byte = 0x7f
-	cborBdIndefiniteArray  byte = 0x9f
-	cborBdIndefiniteMap    byte = 0xbf
-	cborBdBreak            byte = 0xff
-)
-
-// These define some in-stream descriptors for
-// manual encoding e.g. when doing explicit indefinite-length
-const (
-	CborStreamBytes  byte = 0x5f
-	CborStreamString byte = 0x7f
-	CborStreamArray  byte = 0x9f
-	CborStreamMap    byte = 0xbf
-	CborStreamBreak  byte = 0xff
-)
-
-const (
-	cborBaseUint   byte = 0x00
-	cborBaseNegInt byte = 0x20
-	cborBaseBytes  byte = 0x40
-	cborBaseString byte = 0x60
-	cborBaseArray  byte = 0x80
-	cborBaseMap    byte = 0xa0
-	cborBaseTag    byte = 0xc0
-	cborBaseSimple byte = 0xe0
-)
-
-func cbordesc(bd byte) string {
-	switch bd {
-	case cborBdNil:
-		return "nil"
-	case cborBdFalse:
-		return "false"
-	case cborBdTrue:
-		return "true"
-	case cborBdFloat16, cborBdFloat32, cborBdFloat64:
-		return "float"
-	case cborBdIndefiniteBytes:
-		return "bytes*"
-	case cborBdIndefiniteString:
-		return "string*"
-	case cborBdIndefiniteArray:
-		return "array*"
-	case cborBdIndefiniteMap:
-		return "map*"
-	default:
-		switch {
-		case bd >= cborBaseUint && bd < cborBaseNegInt:
-			return "(u)int"
-		case bd >= cborBaseNegInt && bd < cborBaseBytes:
-			return "int"
-		case bd >= cborBaseBytes && bd < cborBaseString:
-			return "bytes"
-		case bd >= cborBaseString && bd < cborBaseArray:
-			return "string"
-		case bd >= cborBaseArray && bd < cborBaseMap:
-			return "array"
-		case bd >= cborBaseMap && bd < cborBaseTag:
-			return "map"
-		case bd >= cborBaseTag && bd < cborBaseSimple:
-			return "ext"
-		default:
-			return "unknown"
-		}
-	}
-}
-
-// -------------------
-
-type cborEncDriver struct {
-	noBuiltInTypes
-	encDriverNoopContainerWriter
-	e *Encoder
-	w *encWriterSwitch
-	h *CborHandle
-	x [8]byte
-	// _ [3]uint64 // padding
-}
-
-func (e *cborEncDriver) EncodeNil() {
-	e.w.writen1(cborBdNil)
-}
-
-func (e *cborEncDriver) EncodeBool(b bool) {
-	if b {
-		e.w.writen1(cborBdTrue)
-	} else {
-		e.w.writen1(cborBdFalse)
-	}
-}
-
-func (e *cborEncDriver) EncodeFloat32(f float32) {
-	e.w.writen1(cborBdFloat32)
-	bigenHelper{e.x[:4], e.w}.writeUint32(math.Float32bits(f))
-}
-
-func (e *cborEncDriver) EncodeFloat64(f float64) {
-	e.w.writen1(cborBdFloat64)
-	bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
-}
-
-func (e *cborEncDriver) encUint(v uint64, bd byte) {
-	if v <= 0x17 {
-		e.w.writen1(byte(v) + bd)
-	} else if v <= math.MaxUint8 {
-		e.w.writen2(bd+0x18, uint8(v))
-	} else if v <= math.MaxUint16 {
-		e.w.writen1(bd + 0x19)
-		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(v))
-	} else if v <= math.MaxUint32 {
-		e.w.writen1(bd + 0x1a)
-		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(v))
-	} else { // if v <= math.MaxUint64 {
-		e.w.writen1(bd + 0x1b)
-		bigenHelper{e.x[:8], e.w}.writeUint64(v)
-	}
-}
-
-func (e *cborEncDriver) EncodeInt(v int64) {
-	if v < 0 {
-		e.encUint(uint64(-1-v), cborBaseNegInt)
-	} else {
-		e.encUint(uint64(v), cborBaseUint)
-	}
-}
-
-func (e *cborEncDriver) EncodeUint(v uint64) {
-	e.encUint(v, cborBaseUint)
-}
-
-func (e *cborEncDriver) encLen(bd byte, length int) {
-	e.encUint(uint64(length), bd)
-}
-
-func (e *cborEncDriver) EncodeTime(t time.Time) {
-	if t.IsZero() {
-		e.EncodeNil()
-	} else if e.h.TimeRFC3339 {
-		e.encUint(0, cborBaseTag)
-		e.EncodeStringEnc(cUTF8, t.Format(time.RFC3339Nano))
-	} else {
-		e.encUint(1, cborBaseTag)
-		t = t.UTC().Round(time.Microsecond)
-		sec, nsec := t.Unix(), uint64(t.Nanosecond())
-		if nsec == 0 {
-			e.EncodeInt(sec)
-		} else {
-			e.EncodeFloat64(float64(sec) + float64(nsec)/1e9)
-		}
-	}
-}
-
-func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
-	e.encUint(uint64(xtag), cborBaseTag)
-	if v := ext.ConvertExt(rv); v == nil {
-		e.EncodeNil()
-	} else {
-		en.encode(v)
-	}
-}
-
-func (e *cborEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
-	e.encUint(uint64(re.Tag), cborBaseTag)
-	// only encodes re.Value (never re.Data)
-	// if false && re.Data != nil {
-	// 	en.encode(re.Data)
-	// } else if re.Value != nil {
-	if re.Value != nil {
-		en.encode(re.Value)
-	} else {
-		e.EncodeNil()
-	}
-}
-
-func (e *cborEncDriver) WriteArrayStart(length int) {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdIndefiniteArray)
-	} else {
-		e.encLen(cborBaseArray, length)
-	}
-}
-
-func (e *cborEncDriver) WriteMapStart(length int) {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdIndefiniteMap)
-	} else {
-		e.encLen(cborBaseMap, length)
-	}
-}
-
-func (e *cborEncDriver) WriteMapEnd() {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdBreak)
-	}
-}
-
-func (e *cborEncDriver) WriteArrayEnd() {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdBreak)
-	}
-}
-
-func (e *cborEncDriver) EncodeString(c charEncoding, v string) {
-	e.encStringBytesS(cborBaseString, v)
-}
-
-func (e *cborEncDriver) EncodeStringEnc(c charEncoding, v string) {
-	e.encStringBytesS(cborBaseString, v)
-}
-
-func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
-	if v == nil {
-		e.EncodeNil()
-	} else if c == cRAW {
-		e.encStringBytesS(cborBaseBytes, stringView(v))
-	} else {
-		e.encStringBytesS(cborBaseString, stringView(v))
-	}
-}
-
-func (e *cborEncDriver) EncodeStringBytesRaw(v []byte) {
-	if v == nil {
-		e.EncodeNil()
-	} else {
-		e.encStringBytesS(cborBaseBytes, stringView(v))
-	}
-}
-
-func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
-	if e.h.IndefiniteLength {
-		if bb == cborBaseBytes {
-			e.w.writen1(cborBdIndefiniteBytes)
-		} else {
-			e.w.writen1(cborBdIndefiniteString)
-		}
-		var vlen uint = uint(len(v))
-		blen := vlen / 4
-		if blen == 0 {
-			blen = 64
-		} else if blen > 1024 {
-			blen = 1024
-		}
-		for i := uint(0); i < vlen; {
-			var v2 string
-			i2 := i + blen
-			if i2 < vlen {
-				v2 = v[i:i2]
-			} else {
-				v2 = v[i:]
-			}
-			e.encLen(bb, len(v2))
-			e.w.writestr(v2)
-			i = i2
-		}
-		e.w.writen1(cborBdBreak)
-	} else {
-		e.encLen(bb, len(v))
-		e.w.writestr(v)
-	}
-}
-
-// ----------------------
-
-type cborDecDriver struct {
-	d      *Decoder
-	h      *CborHandle
-	r      *decReaderSwitch
-	br     bool // bytes reader
-	bdRead bool
-	bd     byte
-	noBuiltInTypes
-	// decNoSeparator
-	decDriverNoopContainerReader
-	// _ [3]uint64 // padding
-}
-
-func (d *cborDecDriver) readNextBd() {
-	d.bd = d.r.readn1()
-	d.bdRead = true
-}
-
-func (d *cborDecDriver) uncacheRead() {
-	if d.bdRead {
-		d.r.unreadn1()
-		d.bdRead = false
-	}
-}
-
-func (d *cborDecDriver) ContainerType() (vt valueType) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == cborBdNil {
-		return valueTypeNil
-	} else if d.bd == cborBdIndefiniteBytes || (d.bd >= cborBaseBytes && d.bd < cborBaseString) {
-		return valueTypeBytes
-	} else if d.bd == cborBdIndefiniteString || (d.bd >= cborBaseString && d.bd < cborBaseArray) {
-		return valueTypeString
-	} else if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
-		return valueTypeArray
-	} else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) {
-		return valueTypeMap
-	}
-	// else {
-	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
-	// }
-	return valueTypeUnset
-}
-
-func (d *cborDecDriver) TryDecodeAsNil() bool {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	// treat Nil and Undefined as nil values
-	if d.bd == cborBdNil || d.bd == cborBdUndefined {
-		d.bdRead = false
-		return true
-	}
-	return false
-}
-
-func (d *cborDecDriver) CheckBreak() bool {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == cborBdBreak {
-		d.bdRead = false
-		return true
-	}
-	return false
-}
-
-func (d *cborDecDriver) decUint() (ui uint64) {
-	v := d.bd & 0x1f
-	if v <= 0x17 {
-		ui = uint64(v)
-	} else {
-		if v == 0x18 {
-			ui = uint64(d.r.readn1())
-		} else if v == 0x19 {
-			ui = uint64(bigen.Uint16(d.r.readx(2)))
-		} else if v == 0x1a {
-			ui = uint64(bigen.Uint32(d.r.readx(4)))
-		} else if v == 0x1b {
-			ui = uint64(bigen.Uint64(d.r.readx(8)))
-		} else {
-			d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd))
-			return
-		}
-	}
-	return
-}
-
-func (d *cborDecDriver) decCheckInteger() (neg bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	major := d.bd >> 5
-	if major == cborMajorUint {
-	} else if major == cborMajorNegInt {
-		neg = true
-	} else {
-		d.d.errorf("not an integer - invalid major %v from descriptor %x/%s",
-			major, d.bd, cbordesc(d.bd))
-		return
-	}
-	return
-}
-
-func (d *cborDecDriver) DecodeInt64() (i int64) {
-	neg := d.decCheckInteger()
-	ui := d.decUint()
-	// check if this number can be converted to an int without overflow
-	if neg {
-		i = -(chkOvf.SignedIntV(ui + 1))
-	} else {
-		i = chkOvf.SignedIntV(ui)
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *cborDecDriver) DecodeUint64() (ui uint64) {
-	if d.decCheckInteger() {
-		d.d.errorf("assigning negative signed value to unsigned type")
-		return
-	}
-	ui = d.decUint()
-	d.bdRead = false
-	return
-}
-
-func (d *cborDecDriver) DecodeFloat64() (f float64) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if bd := d.bd; bd == cborBdFloat16 {
-		f = float64(math.Float32frombits(halfFloatToFloatBits(bigen.Uint16(d.r.readx(2)))))
-	} else if bd == cborBdFloat32 {
-		f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
-	} else if bd == cborBdFloat64 {
-		f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
-	} else if bd >= cborBaseUint && bd < cborBaseBytes {
-		f = float64(d.DecodeInt64())
-	} else {
-		d.d.errorf("float only valid from float16/32/64 - invalid descriptor %x/%s", bd, cbordesc(bd))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-// bool can be decoded from bool only (single byte).
-func (d *cborDecDriver) DecodeBool() (b bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if bd := d.bd; bd == cborBdTrue {
-		b = true
-	} else if bd == cborBdFalse {
-	} else {
-		d.d.errorf("not bool - %s %x/%s", msgBadDesc, d.bd, cbordesc(d.bd))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *cborDecDriver) ReadMapStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	d.bdRead = false
-	if d.bd == cborBdIndefiniteMap {
-		return -1
-	}
-	return d.decLen()
-}
-
-func (d *cborDecDriver) ReadArrayStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	d.bdRead = false
-	if d.bd == cborBdIndefiniteArray {
-		return -1
-	}
-	return d.decLen()
-}
-
-func (d *cborDecDriver) decLen() int {
-	return int(d.decUint())
-}
-
-func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
-	d.bdRead = false
-	for {
-		if d.CheckBreak() {
-			break
-		}
-		if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorText {
-			d.d.errorf("expect bytes/string major type in indefinite string/bytes;"+
-				" got major %v from descriptor %x/%x", major, d.bd, cbordesc(d.bd))
-			return nil
-		}
-		n := d.decLen()
-		oldLen := len(bs)
-		newLen := oldLen + n
-		if newLen > cap(bs) {
-			bs2 := make([]byte, newLen, 2*cap(bs)+n)
-			copy(bs2, bs)
-			bs = bs2
-		} else {
-			bs = bs[:newLen]
-		}
-		d.r.readb(bs[oldLen:newLen])
-		// bs = append(bs, d.r.readn()...)
-		d.bdRead = false
-	}
-	d.bdRead = false
-	return bs
-}
-
-func (d *cborDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == cborBdNil || d.bd == cborBdUndefined {
-		d.bdRead = false
-		return nil
-	}
-	if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
-		d.bdRead = false
-		if bs == nil {
-			if zerocopy {
-				return d.decAppendIndefiniteBytes(d.d.b[:0])
-			}
-			return d.decAppendIndefiniteBytes(zeroByteSlice)
-		}
-		return d.decAppendIndefiniteBytes(bs[:0])
-	}
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	}
-	clen := d.decLen()
-	d.bdRead = false
-	if zerocopy {
-		if d.br {
-			return d.r.readx(uint(clen))
-		} else if len(bs) == 0 {
-			bs = d.d.b[:]
-		}
-	}
-	return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
-}
-
-func (d *cborDecDriver) DecodeString() (s string) {
-	return string(d.DecodeBytes(d.d.b[:], true))
-}
-
-func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
-	return d.DecodeBytes(d.d.b[:], true)
-}
-
-func (d *cborDecDriver) DecodeTime() (t time.Time) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == cborBdNil || d.bd == cborBdUndefined {
-		d.bdRead = false
-		return
-	}
-	xtag := d.decUint()
-	d.bdRead = false
-	return d.decodeTime(xtag)
-}
-
-func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	switch xtag {
-	case 0:
-		var err error
-		if t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes())); err != nil {
-			d.d.errorv(err)
-		}
-	case 1:
-		// decode an int64 or a float, and infer time.Time from there.
-		// for floats, round to microseconds, as that is what is guaranteed to fit well.
-		switch {
-		case d.bd == cborBdFloat16, d.bd == cborBdFloat32:
-			f1, f2 := math.Modf(d.DecodeFloat64())
-			t = time.Unix(int64(f1), int64(f2*1e9))
-		case d.bd == cborBdFloat64:
-			f1, f2 := math.Modf(d.DecodeFloat64())
-			t = time.Unix(int64(f1), int64(f2*1e9))
-		case d.bd >= cborBaseUint && d.bd < cborBaseNegInt,
-			d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
-			t = time.Unix(d.DecodeInt64(), 0)
-		default:
-			d.d.errorf("time.Time can only be decoded from a number (or RFC3339 string)")
-		}
-	default:
-		d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag)
-	}
-	t = t.UTC().Round(time.Microsecond)
-	return
-}
-
-func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	u := d.decUint()
-	d.bdRead = false
-	realxtag = u
-	if ext == nil {
-		re := rv.(*RawExt)
-		re.Tag = realxtag
-		d.d.decode(&re.Value)
-	} else if xtag != realxtag {
-		d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", realxtag, xtag)
-		return
-	} else {
-		var v interface{}
-		d.d.decode(&v)
-		ext.UpdateExt(rv, v)
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *cborDecDriver) DecodeNaked() {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-
-	n := d.d.naked()
-	var decodeFurther bool
-
-	switch d.bd {
-	case cborBdNil:
-		n.v = valueTypeNil
-	case cborBdFalse:
-		n.v = valueTypeBool
-		n.b = false
-	case cborBdTrue:
-		n.v = valueTypeBool
-		n.b = true
-	case cborBdFloat16, cborBdFloat32, cborBdFloat64:
-		n.v = valueTypeFloat
-		n.f = d.DecodeFloat64()
-	case cborBdIndefiniteBytes:
-		n.v = valueTypeBytes
-		n.l = d.DecodeBytes(nil, false)
-	case cborBdIndefiniteString:
-		n.v = valueTypeString
-		n.s = d.DecodeString()
-	case cborBdIndefiniteArray:
-		n.v = valueTypeArray
-		decodeFurther = true
-	case cborBdIndefiniteMap:
-		n.v = valueTypeMap
-		decodeFurther = true
-	default:
-		switch {
-		case d.bd >= cborBaseUint && d.bd < cborBaseNegInt:
-			if d.h.SignedInteger {
-				n.v = valueTypeInt
-				n.i = d.DecodeInt64()
-			} else {
-				n.v = valueTypeUint
-				n.u = d.DecodeUint64()
-			}
-		case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
-			n.v = valueTypeInt
-			n.i = d.DecodeInt64()
-		case d.bd >= cborBaseBytes && d.bd < cborBaseString:
-			n.v = valueTypeBytes
-			n.l = d.DecodeBytes(nil, false)
-		case d.bd >= cborBaseString && d.bd < cborBaseArray:
-			n.v = valueTypeString
-			n.s = d.DecodeString()
-		case d.bd >= cborBaseArray && d.bd < cborBaseMap:
-			n.v = valueTypeArray
-			decodeFurther = true
-		case d.bd >= cborBaseMap && d.bd < cborBaseTag:
-			n.v = valueTypeMap
-			decodeFurther = true
-		case d.bd >= cborBaseTag && d.bd < cborBaseSimple:
-			n.v = valueTypeExt
-			n.u = d.decUint()
-			n.l = nil
-			if n.u == 0 || n.u == 1 {
-				d.bdRead = false
-				n.v = valueTypeTime
-				n.t = d.decodeTime(n.u)
-			}
-			// d.bdRead = false
-			// d.d.decode(&re.Value) // handled by decode itself.
-			// decodeFurther = true
-		default:
-			d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd)
-			return
-		}
-	}
-
-	if !decodeFurther {
-		d.bdRead = false
-	}
-}
-
-// -------------------------
-
-// CborHandle is a Handle for the CBOR encoding format,
-// defined at http://tools.ietf.org/html/rfc7049 and documented further at http://cbor.io .
-//
-// CBOR is comprehensively supported, including support for:
-//   - indefinite-length arrays/maps/bytes/strings
-//   - (extension) tags in range 0..0xffff (0 .. 65535)
-//   - half, single and double-precision floats
-//   - all numbers (1, 2, 4 and 8-byte signed and unsigned integers)
-//   - nil, true, false, ...
-//   - arrays and maps, bytes and text strings
-//
-// None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
-// Users can implement them as needed (using SetExt), including spec-documented ones:
-//   - timestamp, BigNum, BigFloat, Decimals,
-//   - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
-type CborHandle struct {
-	binaryEncodingType
-	noElemSeparators
-	BasicHandle
-
-	// IndefiniteLength=true, means that we encode using indefinitelength
-	IndefiniteLength bool
-
-	// TimeRFC3339 says to encode time.Time using RFC3339 format.
-	// If unset, we encode time.Time using seconds past epoch.
-	TimeRFC3339 bool
-
-	// _ [1]uint64 // padding
-}
-
-// Name returns the name of the handle: cbor
-func (h *CborHandle) Name() string { return "cbor" }
-
-// SetInterfaceExt sets an extension
-func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
-}
-
-func (h *CborHandle) newEncDriver(e *Encoder) encDriver {
-	return &cborEncDriver{e: e, w: e.w, h: h}
-}
-
-func (h *CborHandle) newDecDriver(d *Decoder) decDriver {
-	return &cborDecDriver{d: d, h: h, r: d.r, br: d.bytes}
-}
-
-func (e *cborEncDriver) reset() {
-	e.w = e.e.w
-}
-
-func (d *cborDecDriver) reset() {
-	d.r, d.br = d.d.r, d.d.bytes
-	d.bd, d.bdRead = 0, false
-}
-
-var _ decDriver = (*cborDecDriver)(nil)
-var _ encDriver = (*cborEncDriver)(nil)

+ 0 - 13
vendor/github.com/ugorji/go/codec/codecgen.go

@@ -1,13 +0,0 @@
-// +build codecgen generated
-
-package codec
-
-// this file is here, to set the codecgen variable to true
-// when the build tag codecgen is set.
-//
-// this allows us do specific things e.g. skip missing fields tests,
-// when running in codecgen mode.
-
-func init() {
-	codecgen = true
-}

+ 0 - 3095
vendor/github.com/ugorji/go/codec/decode.go

@@ -1,3095 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"encoding"
-	"errors"
-	"fmt"
-	"io"
-	"reflect"
-	"runtime"
-	"strconv"
-	"time"
-)
-
-// Some tagging information for error messages.
-const (
-	msgBadDesc = "unrecognized descriptor byte"
-	// msgDecCannotExpandArr = "cannot expand go array from %v to stream length: %v"
-)
-
-const (
-	decDefMaxDepth         = 1024 // maximum depth
-	decDefSliceCap         = 8
-	decDefChanCap          = 64            // should be large, as cap cannot be expanded
-	decScratchByteArrayLen = cacheLineSize // + (8 * 2) // - (8 * 1)
-)
-
-var (
-	errstrOnlyMapOrArrayCanDecodeIntoStruct = "only encoded map or array can be decoded into a struct"
-	errstrCannotDecodeIntoNil               = "cannot decode into nil"
-
-	errmsgExpandSliceOverflow     = "expand slice: slice overflow"
-	errmsgExpandSliceCannotChange = "expand slice: cannot change"
-
-	errDecoderNotInitialized = errors.New("Decoder not initialized")
-
-	errDecUnreadByteNothingToRead   = errors.New("cannot unread - nothing has been read")
-	errDecUnreadByteLastByteNotRead = errors.New("cannot unread - last byte has not been read")
-	errDecUnreadByteUnknown         = errors.New("cannot unread - reason unknown")
-	errMaxDepthExceeded             = errors.New("maximum decoding depth exceeded")
-)
-
-/*
-
-// decReader abstracts the reading source, allowing implementations that can
-// read from an io.Reader or directly off a byte slice with zero-copying.
-//
-// Deprecated: Use decReaderSwitch instead.
-type decReader interface {
-	unreadn1()
-	// readx will use the implementation scratch buffer if possible i.e. n < len(scratchbuf), OR
-	// just return a view of the []byte being decoded from.
-	// Ensure you call detachZeroCopyBytes later if this needs to be sent outside codec control.
-	readx(n int) []byte
-	readb([]byte)
-	readn1() uint8
-	numread() uint // number of bytes read
-	track()
-	stopTrack() []byte
-
-	// skip will skip any byte that matches, and return the first non-matching byte
-	skip(accept *bitset256) (token byte)
-	// readTo will read any byte that matches, stopping once no-longer matching.
-	readTo(in []byte, accept *bitset256) (out []byte)
-	// readUntil will read, only stopping once it matches the 'stop' byte.
-	readUntil(in []byte, stop byte) (out []byte)
-}
-
-*/
-
-type decDriver interface {
-	// this will check if the next token is a break.
-	CheckBreak() bool
-	// TryDecodeAsNil tries to decode as nil.
-	// Note: TryDecodeAsNil should be careful not to share any temporary []byte with
-	// the rest of the decDriver. This is because sometimes, we optimize by holding onto
-	// a transient []byte, and ensuring the only other call we make to the decDriver
-	// during that time is maybe a TryDecodeAsNil() call.
-	TryDecodeAsNil() bool
-	// ContainerType returns one of: Bytes, String, Nil, Slice or Map. Return unSet if not known.
-	ContainerType() (vt valueType)
-	// IsBuiltinType(rt uintptr) bool
-
-	// DecodeNaked will decode primitives (number, bool, string, []byte) and RawExt.
-	// For maps and arrays, it will not do the decoding in-band, but will signal
-	// the decoder, so that is done later, by setting the decNaked.valueType field.
-	//
-	// Note: Numbers are decoded as int64, uint64, float64 only (no smaller sized number types).
-	// for extensions, DecodeNaked must read the tag and the []byte if it exists.
-	// if the []byte is not read, then kInterfaceNaked will treat it as a Handle
-	// that stores the subsequent value in-band, and complete reading the RawExt.
-	//
-	// extensions should also use readx to decode them, for efficiency.
-	// kInterface will extract the detached byte slice if it has to pass it outside its realm.
-	DecodeNaked()
-
-	// Deprecated: use DecodeInt64 and DecodeUint64 instead
-	// DecodeInt(bitsize uint8) (i int64)
-	// DecodeUint(bitsize uint8) (ui uint64)
-
-	DecodeInt64() (i int64)
-	DecodeUint64() (ui uint64)
-
-	DecodeFloat64() (f float64)
-	DecodeBool() (b bool)
-	// DecodeString can also decode symbols.
-	// It looks redundant as DecodeBytes is available.
-	// However, some codecs (e.g. binc) support symbols and can
-	// return a pre-stored string value, meaning that it can bypass
-	// the cost of []byte->string conversion.
-	DecodeString() (s string)
-	DecodeStringAsBytes() (v []byte)
-
-	// DecodeBytes may be called directly, without going through reflection.
-	// Consequently, it must be designed to handle possible nil.
-	DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
-	// DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte)
-
-	// decodeExt will decode into a *RawExt or into an extension.
-	DecodeExt(v interface{}, xtag uint64, ext Ext) (realxtag uint64)
-	// decodeExt(verifyTag bool, tag byte) (xtag byte, xbs []byte)
-
-	DecodeTime() (t time.Time)
-
-	ReadArrayStart() int
-	ReadArrayElem()
-	ReadArrayEnd()
-	ReadMapStart() int
-	ReadMapElemKey()
-	ReadMapElemValue()
-	ReadMapEnd()
-
-	reset()
-	uncacheRead()
-}
-
-type decodeError struct {
-	codecError
-	pos int
-}
-
-func (d decodeError) Error() string {
-	return fmt.Sprintf("%s decode error [pos %d]: %v", d.name, d.pos, d.err)
-}
-
-type decDriverNoopContainerReader struct{}
-
-func (x decDriverNoopContainerReader) ReadArrayStart() (v int) { return }
-func (x decDriverNoopContainerReader) ReadArrayElem()          {}
-func (x decDriverNoopContainerReader) ReadArrayEnd()           {}
-func (x decDriverNoopContainerReader) ReadMapStart() (v int)   { return }
-func (x decDriverNoopContainerReader) ReadMapElemKey()         {}
-func (x decDriverNoopContainerReader) ReadMapElemValue()       {}
-func (x decDriverNoopContainerReader) ReadMapEnd()             {}
-func (x decDriverNoopContainerReader) CheckBreak() (v bool)    { return }
-
-// func (x decNoSeparator) uncacheRead() {}
-
-// DecodeOptions captures configuration options during decode.
-type DecodeOptions struct {
-	// MapType specifies type to use during schema-less decoding of a map in the stream.
-	// If nil (unset), we default to map[string]interface{} iff json handle and MapStringAsKey=true,
-	// else map[interface{}]interface{}.
-	MapType reflect.Type
-
-	// SliceType specifies type to use during schema-less decoding of an array in the stream.
-	// If nil (unset), we default to []interface{} for all formats.
-	SliceType reflect.Type
-
-	// MaxInitLen defines the maxinum initial length that we "make" a collection
-	// (string, slice, map, chan). If 0 or negative, we default to a sensible value
-	// based on the size of an element in the collection.
-	//
-	// For example, when decoding, a stream may say that it has 2^64 elements.
-	// We should not auto-matically provision a slice of that size, to prevent Out-Of-Memory crash.
-	// Instead, we provision up to MaxInitLen, fill that up, and start appending after that.
-	MaxInitLen int
-
-	// ReaderBufferSize is the size of the buffer used when reading.
-	//
-	// if > 0, we use a smart buffer internally for performance purposes.
-	ReaderBufferSize int
-
-	// MaxDepth defines the maximum depth when decoding nested
-	// maps and slices. If 0 or negative, we default to a suitably large number (currently 1024).
-	MaxDepth int16
-
-	// If ErrorIfNoField, return an error when decoding a map
-	// from a codec stream into a struct, and no matching struct field is found.
-	ErrorIfNoField bool
-
-	// If ErrorIfNoArrayExpand, return an error when decoding a slice/array that cannot be expanded.
-	// For example, the stream contains an array of 8 items, but you are decoding into a [4]T array,
-	// or you are decoding into a slice of length 4 which is non-addressable (and so cannot be set).
-	ErrorIfNoArrayExpand bool
-
-	// If SignedInteger, use the int64 during schema-less decoding of unsigned values (not uint64).
-	SignedInteger bool
-
-	// MapValueReset controls how we decode into a map value.
-	//
-	// By default, we MAY retrieve the mapping for a key, and then decode into that.
-	// However, especially with big maps, that retrieval may be expensive and unnecessary
-	// if the stream already contains all that is necessary to recreate the value.
-	//
-	// If true, we will never retrieve the previous mapping,
-	// but rather decode into a new value and set that in the map.
-	//
-	// If false, we will retrieve the previous mapping if necessary e.g.
-	// the previous mapping is a pointer, or is a struct or array with pre-set state,
-	// or is an interface.
-	MapValueReset bool
-
-	// SliceElementReset: on decoding a slice, reset the element to a zero value first.
-	//
-	// concern: if the slice already contained some garbage, we will decode into that garbage.
-	SliceElementReset bool
-
-	// InterfaceReset controls how we decode into an interface.
-	//
-	// By default, when we see a field that is an interface{...},
-	// or a map with interface{...} value, we will attempt decoding into the
-	// "contained" value.
-	//
-	// However, this prevents us from reading a string into an interface{}
-	// that formerly contained a number.
-	//
-	// If true, we will decode into a new "blank" value, and set that in the interface.
-	// If false, we will decode into whatever is contained in the interface.
-	InterfaceReset bool
-
-	// InternString controls interning of strings during decoding.
-	//
-	// Some handles, e.g. json, typically will read map keys as strings.
-	// If the set of keys are finite, it may help reduce allocation to
-	// look them up from a map (than to allocate them afresh).
-	//
-	// Note: Handles will be smart when using the intern functionality.
-	// Every string should not be interned.
-	// An excellent use-case for interning is struct field names,
-	// or map keys where key type is string.
-	InternString bool
-
-	// PreferArrayOverSlice controls whether to decode to an array or a slice.
-	//
-	// This only impacts decoding into a nil interface{}.
-	// Consequently, it has no effect on codecgen.
-	//
-	// *Note*: This only applies if using go1.5 and above,
-	// as it requires reflect.ArrayOf support which was absent before go1.5.
-	PreferArrayOverSlice bool
-
-	// DeleteOnNilMapValue controls how to decode a nil value in the stream.
-	//
-	// If true, we will delete the mapping of the key.
-	// Else, just set the mapping to the zero value of the type.
-	DeleteOnNilMapValue bool
-}
-
-// ------------------------------------------------
-
-type unreadByteStatus uint8
-
-// unreadByteStatus goes from
-// undefined (when initialized) -- (read) --> canUnread -- (unread) --> canRead ...
-const (
-	unreadByteUndefined unreadByteStatus = iota
-	unreadByteCanRead
-	unreadByteCanUnread
-)
-
-type ioDecReaderCommon struct {
-	r io.Reader // the reader passed in
-
-	n uint // num read
-
-	l   byte             // last byte
-	ls  unreadByteStatus // last byte status
-	trb bool             // tracking bytes turned on
-	_   bool
-	b   [4]byte // tiny buffer for reading single bytes
-
-	tr []byte // tracking bytes read
-}
-
-func (z *ioDecReaderCommon) reset(r io.Reader) {
-	z.r = r
-	z.ls = unreadByteUndefined
-	z.l, z.n = 0, 0
-	z.trb = false
-	if z.tr != nil {
-		z.tr = z.tr[:0]
-	}
-}
-
-func (z *ioDecReaderCommon) numread() uint {
-	return z.n
-}
-
-func (z *ioDecReaderCommon) track() {
-	if z.tr != nil {
-		z.tr = z.tr[:0]
-	}
-	z.trb = true
-}
-
-func (z *ioDecReaderCommon) stopTrack() (bs []byte) {
-	z.trb = false
-	return z.tr
-}
-
-// ------------------------------------------
-
-// ioDecReader is a decReader that reads off an io.Reader.
-//
-// It also has a fallback implementation of ByteScanner if needed.
-type ioDecReader struct {
-	ioDecReaderCommon
-
-	rr io.Reader
-	br io.ByteScanner
-
-	x [scratchByteArrayLen]byte // for: get struct field name, swallow valueTypeBytes, etc
-	_ [1]uint64                 // padding
-}
-
-func (z *ioDecReader) reset(r io.Reader) {
-	z.ioDecReaderCommon.reset(r)
-
-	var ok bool
-	z.rr = r
-	z.br, ok = r.(io.ByteScanner)
-	if !ok {
-		z.br = z
-		z.rr = z
-	}
-}
-
-func (z *ioDecReader) Read(p []byte) (n int, err error) {
-	if len(p) == 0 {
-		return
-	}
-	var firstByte bool
-	if z.ls == unreadByteCanRead {
-		z.ls = unreadByteCanUnread
-		p[0] = z.l
-		if len(p) == 1 {
-			n = 1
-			return
-		}
-		firstByte = true
-		p = p[1:]
-	}
-	n, err = z.r.Read(p)
-	if n > 0 {
-		if err == io.EOF && n == len(p) {
-			err = nil // read was successful, so postpone EOF (till next time)
-		}
-		z.l = p[n-1]
-		z.ls = unreadByteCanUnread
-	}
-	if firstByte {
-		n++
-	}
-	return
-}
-
-func (z *ioDecReader) ReadByte() (c byte, err error) {
-	n, err := z.Read(z.b[:1])
-	if n == 1 {
-		c = z.b[0]
-		if err == io.EOF {
-			err = nil // read was successful, so postpone EOF (till next time)
-		}
-	}
-	return
-}
-
-func (z *ioDecReader) UnreadByte() (err error) {
-	switch z.ls {
-	case unreadByteCanUnread:
-		z.ls = unreadByteCanRead
-	case unreadByteCanRead:
-		err = errDecUnreadByteLastByteNotRead
-	case unreadByteUndefined:
-		err = errDecUnreadByteNothingToRead
-	default:
-		err = errDecUnreadByteUnknown
-	}
-	return
-}
-
-func (z *ioDecReader) readx(n uint) (bs []byte) {
-	if n == 0 {
-		return
-	}
-	if n < uint(len(z.x)) {
-		bs = z.x[:n]
-	} else {
-		bs = make([]byte, n)
-	}
-	if _, err := decReadFull(z.rr, bs); err != nil {
-		panic(err)
-	}
-	z.n += uint(len(bs))
-	if z.trb {
-		z.tr = append(z.tr, bs...)
-	}
-	return
-}
-
-func (z *ioDecReader) readb(bs []byte) {
-	if len(bs) == 0 {
-		return
-	}
-	if _, err := decReadFull(z.rr, bs); err != nil {
-		panic(err)
-	}
-	z.n += uint(len(bs))
-	if z.trb {
-		z.tr = append(z.tr, bs...)
-	}
-}
-
-func (z *ioDecReader) readn1eof() (b uint8, eof bool) {
-	b, err := z.br.ReadByte()
-	if err == nil {
-		z.n++
-		if z.trb {
-			z.tr = append(z.tr, b)
-		}
-	} else if err == io.EOF {
-		eof = true
-	} else {
-		panic(err)
-	}
-	return
-}
-
-func (z *ioDecReader) readn1() (b uint8) {
-	b, err := z.br.ReadByte()
-	if err == nil {
-		z.n++
-		if z.trb {
-			z.tr = append(z.tr, b)
-		}
-		return
-	}
-	panic(err)
-}
-
-func (z *ioDecReader) skip(accept *bitset256) (token byte) {
-	var eof bool
-	// for {
-	// 	token, eof = z.readn1eof()
-	// 	if eof {
-	// 		return
-	// 	}
-	// 	if accept.isset(token) {
-	// 		continue
-	// 	}
-	// 	return
-	// }
-LOOP:
-	token, eof = z.readn1eof()
-	if eof {
-		return
-	}
-	if accept.isset(token) {
-		goto LOOP
-	}
-	return
-}
-
-func (z *ioDecReader) readTo(in []byte, accept *bitset256) []byte {
-	// out = in
-
-	// for {
-	// 	token, eof := z.readn1eof()
-	// 	if eof {
-	// 		return
-	// 	}
-	// 	if accept.isset(token) {
-	// 		out = append(out, token)
-	// 	} else {
-	// 		z.unreadn1()
-	// 		return
-	// 	}
-	// }
-LOOP:
-	token, eof := z.readn1eof()
-	if eof {
-		return in
-	}
-	if accept.isset(token) {
-		// out = append(out, token)
-		in = append(in, token)
-		goto LOOP
-	}
-	z.unreadn1()
-	return in
-}
-
-func (z *ioDecReader) readUntil(in []byte, stop byte) (out []byte) {
-	out = in
-	// for {
-	// 	token, eof := z.readn1eof()
-	// 	if eof {
-	// 		panic(io.EOF)
-	// 	}
-	// 	out = append(out, token)
-	// 	if token == stop {
-	// 		return
-	// 	}
-	// }
-LOOP:
-	token, eof := z.readn1eof()
-	if eof {
-		panic(io.EOF)
-	}
-	out = append(out, token)
-	if token == stop {
-		return
-	}
-	goto LOOP
-}
-
-//go:noinline
-func (z *ioDecReader) unreadn1() {
-	err := z.br.UnreadByte()
-	if err != nil {
-		panic(err)
-	}
-	z.n--
-	if z.trb {
-		if l := len(z.tr) - 1; l >= 0 {
-			z.tr = z.tr[:l]
-		}
-	}
-}
-
-// ------------------------------------
-
-type bufioDecReader struct {
-	ioDecReaderCommon
-
-	c   uint // cursor
-	buf []byte
-
-	bytesBufPooler
-
-	// err error
-
-	// Extensions can call Decode() within a current Decode() call.
-	// We need to know when the top level Decode() call returns,
-	// so we can decide whether to Release() or not.
-	calls uint16 // what depth in mustDecode are we in now.
-
-	_ [6]uint8 // padding
-
-	_ [1]uint64 // padding
-}
-
-func (z *bufioDecReader) reset(r io.Reader, bufsize int) {
-	z.ioDecReaderCommon.reset(r)
-	z.c = 0
-	z.calls = 0
-	if cap(z.buf) >= bufsize {
-		z.buf = z.buf[:0]
-	} else {
-		z.buf = z.bytesBufPooler.get(bufsize)[:0]
-		// z.buf = make([]byte, 0, bufsize)
-	}
-}
-
-func (z *bufioDecReader) release() {
-	z.buf = nil
-	z.bytesBufPooler.end()
-}
-
-func (z *bufioDecReader) readb(p []byte) {
-	var n = uint(copy(p, z.buf[z.c:]))
-	z.n += n
-	z.c += n
-	if len(p) == int(n) {
-		if z.trb {
-			z.tr = append(z.tr, p...) // cost=9
-		}
-	} else {
-		z.readbFill(p, n)
-	}
-}
-
-//go:noinline - fallback when z.buf is consumed
-func (z *bufioDecReader) readbFill(p0 []byte, n uint) {
-	// at this point, there's nothing in z.buf to read (z.buf is fully consumed)
-	p := p0[n:]
-	var n2 uint
-	var err error
-	if len(p) > cap(z.buf) {
-		n2, err = decReadFull(z.r, p)
-		if err != nil {
-			panic(err)
-		}
-		n += n2
-		z.n += n2
-		// always keep last byte in z.buf
-		z.buf = z.buf[:1]
-		z.buf[0] = p[len(p)-1]
-		z.c = 1
-		if z.trb {
-			z.tr = append(z.tr, p0[:n]...)
-		}
-		return
-	}
-	// z.c is now 0, and len(p) <= cap(z.buf)
-LOOP:
-	// for len(p) > 0 && z.err == nil {
-	if len(p) > 0 {
-		z.buf = z.buf[0:cap(z.buf)]
-		var n1 int
-		n1, err = z.r.Read(z.buf)
-		n2 = uint(n1)
-		if n2 == 0 && err != nil {
-			panic(err)
-		}
-		z.buf = z.buf[:n2]
-		n2 = uint(copy(p, z.buf))
-		z.c = n2
-		n += n2
-		z.n += n2
-		p = p[n2:]
-		goto LOOP
-	}
-	if z.c == 0 {
-		z.buf = z.buf[:1]
-		z.buf[0] = p[len(p)-1]
-		z.c = 1
-	}
-	if z.trb {
-		z.tr = append(z.tr, p0[:n]...)
-	}
-}
-
-func (z *bufioDecReader) readn1() (b byte) {
-	// fast-path, so we elide calling into Read() most of the time
-	if z.c < uint(len(z.buf)) {
-		b = z.buf[z.c]
-		z.c++
-		z.n++
-		if z.trb {
-			z.tr = append(z.tr, b)
-		}
-	} else { // meaning z.c == len(z.buf) or greater ... so need to fill
-		z.readbFill(z.b[:1], 0)
-		b = z.b[0]
-	}
-	return
-}
-
-func (z *bufioDecReader) unreadn1() {
-	if z.c == 0 {
-		panic(errDecUnreadByteNothingToRead)
-	}
-	z.c--
-	z.n--
-	if z.trb {
-		z.tr = z.tr[:len(z.tr)-1]
-	}
-}
-
-func (z *bufioDecReader) readx(n uint) (bs []byte) {
-	if n == 0 {
-		// return
-	} else if z.c+n <= uint(len(z.buf)) {
-		bs = z.buf[z.c : z.c+n]
-		z.n += n
-		z.c += n
-		if z.trb {
-			z.tr = append(z.tr, bs...)
-		}
-	} else {
-		bs = make([]byte, n)
-		// n no longer used - can reuse
-		n = uint(copy(bs, z.buf[z.c:]))
-		z.n += n
-		z.c += n
-		z.readbFill(bs, n)
-	}
-	return
-}
-
-//go:noinline - track called by Decoder.nextValueBytes() (called by jsonUnmarshal,rawBytes)
-func (z *bufioDecReader) doTrack(y uint) {
-	z.tr = append(z.tr, z.buf[z.c:y]...) // cost=14???
-}
-
-func (z *bufioDecReader) skipLoopFn(i uint) {
-	z.n += (i - z.c) - 1
-	i++
-	if z.trb {
-		// z.tr = append(z.tr, z.buf[z.c:i]...)
-		z.doTrack(i)
-	}
-	z.c = i
-}
-
-func (z *bufioDecReader) skip(accept *bitset256) (token byte) {
-	// token, _ = z.search(nil, accept, 0, 1); return
-
-	// for i := z.c; i < len(z.buf); i++ {
-	// 	if token = z.buf[i]; !accept.isset(token) {
-	// 		z.skipLoopFn(i)
-	// 		return
-	// 	}
-	// }
-
-	i := z.c
-LOOP:
-	if i < uint(len(z.buf)) {
-		// inline z.skipLoopFn(i) and refactor, so cost is within inline budget
-		token = z.buf[i]
-		i++
-		if accept.isset(token) {
-			goto LOOP
-		}
-		z.n += i - 2 - z.c
-		if z.trb {
-			z.doTrack(i)
-		}
-		z.c = i
-		return
-	}
-	return z.skipFill(accept)
-}
-
-func (z *bufioDecReader) skipFill(accept *bitset256) (token byte) {
-	z.n += uint(len(z.buf)) - z.c
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:]...)
-	}
-	var n2 int
-	var err error
-	for {
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n2, err = z.r.Read(z.buf)
-		if n2 == 0 && err != nil {
-			panic(err)
-		}
-		z.buf = z.buf[:n2]
-		var i int
-		for i, token = range z.buf {
-			if !accept.isset(token) {
-				z.skipLoopFn(uint(i))
-				return
-			}
-		}
-		// for i := 0; i < n2; i++ {
-		// 	if token = z.buf[i]; !accept.isset(token) {
-		// 		z.skipLoopFn(i)
-		// 		return
-		// 	}
-		// }
-		z.n += uint(n2)
-		if z.trb {
-			z.tr = append(z.tr, z.buf...)
-		}
-	}
-}
-
-func (z *bufioDecReader) readToLoopFn(i uint, out0 []byte) (out []byte) {
-	// out0 is never nil
-	z.n += (i - z.c) - 1
-	out = append(out0, z.buf[z.c:i]...)
-	if z.trb {
-		z.doTrack(i)
-	}
-	z.c = i
-	return
-}
-
-func (z *bufioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
-	// _, out = z.search(in, accept, 0, 2); return
-
-	// for i := z.c; i < len(z.buf); i++ {
-	// 	if !accept.isset(z.buf[i]) {
-	// 		return z.readToLoopFn(i, nil)
-	// 	}
-	// }
-
-	i := z.c
-LOOP:
-	if i < uint(len(z.buf)) {
-		if !accept.isset(z.buf[i]) {
-			// return z.readToLoopFn(i, nil)
-			// inline readToLoopFn here (for performance)
-			z.n += (i - z.c) - 1
-			out = z.buf[z.c:i]
-			if z.trb {
-				z.doTrack(i)
-			}
-			z.c = i
-			return
-		}
-		i++
-		goto LOOP
-	}
-	return z.readToFill(in, accept)
-}
-
-func (z *bufioDecReader) readToFill(in []byte, accept *bitset256) (out []byte) {
-	z.n += uint(len(z.buf)) - z.c
-	out = append(in, z.buf[z.c:]...)
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:]...)
-	}
-	var n2 int
-	var err error
-	for {
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n2, err = z.r.Read(z.buf)
-		if n2 == 0 && err != nil {
-			if err == io.EOF {
-				return // readTo should read until it matches or end is reached
-			}
-			panic(err)
-		}
-		z.buf = z.buf[:n2]
-		for i, token := range z.buf {
-			if !accept.isset(token) {
-				return z.readToLoopFn(uint(i), out)
-			}
-		}
-		// for i := 0; i < n2; i++ {
-		// 	if !accept.isset(z.buf[i]) {
-		// 		return z.readToLoopFn(i, out)
-		// 	}
-		// }
-		out = append(out, z.buf...)
-		z.n += uint(n2)
-		if z.trb {
-			z.tr = append(z.tr, z.buf...)
-		}
-	}
-}
-
-func (z *bufioDecReader) readUntilLoopFn(i uint, out0 []byte) (out []byte) {
-	z.n += (i - z.c) - 1
-	i++
-	out = append(out0, z.buf[z.c:i]...)
-	if z.trb {
-		// z.tr = append(z.tr, z.buf[z.c:i]...)
-		z.doTrack(i)
-	}
-	z.c = i
-	return
-}
-
-func (z *bufioDecReader) readUntil(in []byte, stop byte) (out []byte) {
-	// _, out = z.search(in, nil, stop, 4); return
-
-	// for i := z.c; i < len(z.buf); i++ {
-	// 	if z.buf[i] == stop {
-	// 		return z.readUntilLoopFn(i, nil)
-	// 	}
-	// }
-
-	i := z.c
-LOOP:
-	if i < uint(len(z.buf)) {
-		if z.buf[i] == stop {
-			// inline readUntilLoopFn
-			// return z.readUntilLoopFn(i, nil)
-			z.n += (i - z.c) - 1
-			i++
-			out = z.buf[z.c:i]
-			if z.trb {
-				z.doTrack(i)
-			}
-			z.c = i
-			return
-		}
-		i++
-		goto LOOP
-	}
-	return z.readUntilFill(in, stop)
-}
-
-func (z *bufioDecReader) readUntilFill(in []byte, stop byte) (out []byte) {
-	z.n += uint(len(z.buf)) - z.c
-	out = append(in, z.buf[z.c:]...)
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:]...)
-	}
-	var n1 int
-	var n2 uint
-	var err error
-	for {
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n1, err = z.r.Read(z.buf)
-		n2 = uint(n1)
-		if n2 == 0 && err != nil {
-			panic(err)
-		}
-		z.buf = z.buf[:n2]
-		for i, token := range z.buf {
-			if token == stop {
-				return z.readUntilLoopFn(uint(i), out)
-			}
-		}
-		// for i := 0; i < n2; i++ {
-		// 	if z.buf[i] == stop {
-		// 		return z.readUntilLoopFn(i, out)
-		// 	}
-		// }
-		out = append(out, z.buf...)
-		z.n += n2
-		if z.trb {
-			z.tr = append(z.tr, z.buf...)
-		}
-	}
-}
-
-// ------------------------------------
-
-var errBytesDecReaderCannotUnread = errors.New("cannot unread last byte read")
-
-// bytesDecReader is a decReader that reads off a byte slice with zero copying
-type bytesDecReader struct {
-	b []byte // data
-	c uint   // cursor
-	t uint   // track start
-	// a int    // available
-}
-
-func (z *bytesDecReader) reset(in []byte) {
-	z.b = in
-	// z.a = len(in)
-	z.c = 0
-	z.t = 0
-}
-
-func (z *bytesDecReader) numread() uint {
-	return z.c
-}
-
-func (z *bytesDecReader) unreadn1() {
-	if z.c == 0 || len(z.b) == 0 {
-		panic(errBytesDecReaderCannotUnread)
-	}
-	z.c--
-	// z.a++
-}
-
-func (z *bytesDecReader) readx(n uint) (bs []byte) {
-	// slicing from a non-constant start position is more expensive,
-	// as more computation is required to decipher the pointer start position.
-	// However, we do it only once, and it's better than reslicing both z.b and return value.
-
-	// if n <= 0 {
-	// } else if z.a == 0 {
-	// 	panic(io.EOF)
-	// } else if n > z.a {
-	// 	panic(io.ErrUnexpectedEOF)
-	// } else {
-	// 	c0 := z.c
-	// 	z.c = c0 + n
-	// 	z.a = z.a - n
-	// 	bs = z.b[c0:z.c]
-	// }
-	// return
-
-	if n != 0 {
-		z.c += n
-		if z.c > uint(len(z.b)) {
-			z.c = uint(len(z.b))
-			panic(io.EOF)
-		}
-		bs = z.b[z.c-n : z.c]
-	}
-	return
-
-	// if n == 0 {
-	// } else if z.c+n > uint(len(z.b)) {
-	// 	z.c = uint(len(z.b))
-	// 	panic(io.EOF)
-	// } else {
-	// 	z.c += n
-	// 	bs = z.b[z.c-n : z.c]
-	// }
-	// return
-
-	// if n == 0 {
-	// 	return
-	// }
-	// if z.c == uint(len(z.b)) {
-	// 	panic(io.EOF)
-	// }
-	// if z.c+n > uint(len(z.b)) {
-	// 	panic(io.ErrUnexpectedEOF)
-	// }
-	// // z.a -= n
-	// z.c += n
-	// return z.b[z.c-n : z.c]
-}
-
-func (z *bytesDecReader) readb(bs []byte) {
-	copy(bs, z.readx(uint(len(bs))))
-}
-
-func (z *bytesDecReader) readn1() (v uint8) {
-	if z.c == uint(len(z.b)) {
-		panic(io.EOF)
-	}
-	v = z.b[z.c]
-	z.c++
-	// z.a--
-	return
-}
-
-// func (z *bytesDecReader) readn1eof() (v uint8, eof bool) {
-// 	if z.a == 0 {
-// 		eof = true
-// 		return
-// 	}
-// 	v = z.b[z.c]
-// 	z.c++
-// 	z.a--
-// 	return
-// }
-
-func (z *bytesDecReader) skip(accept *bitset256) (token byte) {
-	i := z.c
-	// if i == len(z.b) {
-	// 	goto END
-	// 	// panic(io.EOF)
-	// }
-
-	// Replace loop with goto construct, so that this can be inlined
-	// for i := z.c; i < blen; i++ {
-	// 	if !accept.isset(z.b[i]) {
-	// 		token = z.b[i]
-	// 		i++
-	// 		z.a -= (i - z.c)
-	// 		z.c = i
-	// 		return
-	// 	}
-	// }
-
-	// i := z.c
-LOOP:
-	if i < uint(len(z.b)) {
-		token = z.b[i]
-		i++
-		if accept.isset(token) {
-			goto LOOP
-		}
-		// z.a -= (i - z.c)
-		z.c = i
-		return
-	}
-	// END:
-	panic(io.EOF)
-	// // z.a = 0
-	// z.c = blen
-	// return
-}
-
-func (z *bytesDecReader) readTo(_ []byte, accept *bitset256) (out []byte) {
-	return z.readToNoInput(accept)
-}
-
-func (z *bytesDecReader) readToNoInput(accept *bitset256) (out []byte) {
-	i := z.c
-	if i == uint(len(z.b)) {
-		panic(io.EOF)
-	}
-
-	// Replace loop with goto construct, so that this can be inlined
-	// for i := z.c; i < blen; i++ {
-	// 	if !accept.isset(z.b[i]) {
-	// 		out = z.b[z.c:i]
-	// 		z.a -= (i - z.c)
-	// 		z.c = i
-	// 		return
-	// 	}
-	// }
-	// out = z.b[z.c:]
-	// z.a, z.c = 0, blen
-	// return
-
-	// 	i := z.c
-	// LOOP:
-	// 	if i < blen {
-	// 		if accept.isset(z.b[i]) {
-	// 			i++
-	// 			goto LOOP
-	// 		}
-	// 		out = z.b[z.c:i]
-	// 		z.a -= (i - z.c)
-	// 		z.c = i
-	// 		return
-	// 	}
-	// 	out = z.b[z.c:]
-	// 	// z.a, z.c = 0, blen
-	// 	z.a = 0
-	// 	z.c = blen
-	// 	return
-
-	// c := i
-LOOP:
-	if i < uint(len(z.b)) {
-		if accept.isset(z.b[i]) {
-			i++
-			goto LOOP
-		}
-	}
-
-	out = z.b[z.c:i]
-	// z.a -= (i - z.c)
-	z.c = i
-	return // z.b[c:i]
-	// z.c, i = i, z.c
-	// return z.b[i:z.c]
-}
-
-func (z *bytesDecReader) readUntil(_ []byte, stop byte) (out []byte) {
-	return z.readUntilNoInput(stop)
-}
-
-func (z *bytesDecReader) readUntilNoInput(stop byte) (out []byte) {
-	i := z.c
-	// if i == len(z.b) {
-	// 	panic(io.EOF)
-	// }
-
-	// Replace loop with goto construct, so that this can be inlined
-	// for i := z.c; i < blen; i++ {
-	// 	if z.b[i] == stop {
-	// 		i++
-	// 		out = z.b[z.c:i]
-	// 		z.a -= (i - z.c)
-	// 		z.c = i
-	// 		return
-	// 	}
-	// }
-LOOP:
-	if i < uint(len(z.b)) {
-		if z.b[i] == stop {
-			i++
-			out = z.b[z.c:i]
-			// z.a -= (i - z.c)
-			z.c = i
-			return
-		}
-		i++
-		goto LOOP
-	}
-	// z.a = 0
-	// z.c = blen
-	panic(io.EOF)
-}
-
-func (z *bytesDecReader) track() {
-	z.t = z.c
-}
-
-func (z *bytesDecReader) stopTrack() (bs []byte) {
-	return z.b[z.t:z.c]
-}
-
-// ----------------------------------------
-
-// func (d *Decoder) builtin(f *codecFnInfo, rv reflect.Value) {
-// 	d.d.DecodeBuiltin(f.ti.rtid, rv2i(rv))
-// }
-
-func (d *Decoder) rawExt(f *codecFnInfo, rv reflect.Value) {
-	d.d.DecodeExt(rv2i(rv), 0, nil)
-}
-
-func (d *Decoder) ext(f *codecFnInfo, rv reflect.Value) {
-	d.d.DecodeExt(rv2i(rv), f.xfTag, f.xfFn)
-}
-
-func (d *Decoder) selferUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	rv2i(rv).(Selfer).CodecDecodeSelf(d)
-}
-
-func (d *Decoder) binaryUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	bm := rv2i(rv).(encoding.BinaryUnmarshaler)
-	xbs := d.d.DecodeBytes(nil, true)
-	if fnerr := bm.UnmarshalBinary(xbs); fnerr != nil {
-		panic(fnerr)
-	}
-}
-
-func (d *Decoder) textUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	tm := rv2i(rv).(encoding.TextUnmarshaler)
-	fnerr := tm.UnmarshalText(d.d.DecodeStringAsBytes())
-	if fnerr != nil {
-		panic(fnerr)
-	}
-}
-
-func (d *Decoder) jsonUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	tm := rv2i(rv).(jsonUnmarshaler)
-	// bs := d.d.DecodeBytes(d.b[:], true, true)
-	// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
-	fnerr := tm.UnmarshalJSON(d.nextValueBytes())
-	if fnerr != nil {
-		panic(fnerr)
-	}
-}
-
-func (d *Decoder) kErr(f *codecFnInfo, rv reflect.Value) {
-	d.errorf("no decoding function defined for kind %v", rv.Kind())
-}
-
-// var kIntfCtr uint64
-
-func (d *Decoder) kInterfaceNaked(f *codecFnInfo) (rvn reflect.Value) {
-	// nil interface:
-	// use some hieristics to decode it appropriately
-	// based on the detected next value in the stream.
-	n := d.naked()
-	d.d.DecodeNaked()
-	if n.v == valueTypeNil {
-		return
-	}
-	// We cannot decode non-nil stream value into nil interface with methods (e.g. io.Reader).
-	if f.ti.numMeth > 0 {
-		d.errorf("cannot decode non-nil codec value into nil %v (%v methods)", f.ti.rt, f.ti.numMeth)
-		return
-	}
-	// var useRvn bool
-	switch n.v {
-	case valueTypeMap:
-		// if json, default to a map type with string keys
-		mtid := d.mtid
-		if mtid == 0 {
-			if d.jsms {
-				mtid = mapStrIntfTypId
-			} else {
-				mtid = mapIntfIntfTypId
-			}
-		}
-		if mtid == mapIntfIntfTypId {
-			var v2 map[interface{}]interface{}
-			d.decode(&v2)
-			rvn = reflect.ValueOf(&v2).Elem()
-		} else if mtid == mapStrIntfTypId { // for json performance
-			var v2 map[string]interface{}
-			d.decode(&v2)
-			rvn = reflect.ValueOf(&v2).Elem()
-		} else {
-			if d.mtr {
-				rvn = reflect.New(d.h.MapType)
-				d.decode(rv2i(rvn))
-				rvn = rvn.Elem()
-			} else {
-				rvn = reflect.New(d.h.MapType).Elem()
-				d.decodeValue(rvn, nil, true)
-			}
-		}
-	case valueTypeArray:
-		if d.stid == 0 || d.stid == intfSliceTypId {
-			var v2 []interface{}
-			d.decode(&v2)
-			rvn = reflect.ValueOf(&v2).Elem()
-			if reflectArrayOfSupported && d.stid == 0 && d.h.PreferArrayOverSlice {
-				rvn2 := reflect.New(reflectArrayOf(rvn.Len(), intfTyp)).Elem()
-				reflect.Copy(rvn2, rvn)
-				rvn = rvn2
-			}
-		} else {
-			if d.str {
-				rvn = reflect.New(d.h.SliceType)
-				d.decode(rv2i(rvn))
-				rvn = rvn.Elem()
-			} else {
-				rvn = reflect.New(d.h.SliceType).Elem()
-				d.decodeValue(rvn, nil, true)
-			}
-		}
-	case valueTypeExt:
-		var v interface{}
-		tag, bytes := n.u, n.l // calling decode below might taint the values
-		if bytes == nil {
-			d.decode(&v)
-		}
-		bfn := d.h.getExtForTag(tag)
-		if bfn == nil {
-			var re RawExt
-			re.Tag = tag
-			re.Data = detachZeroCopyBytes(d.bytes, nil, bytes)
-			re.Value = v
-			rvn = reflect.ValueOf(&re).Elem()
-		} else {
-			rvnA := reflect.New(bfn.rt)
-			if bytes != nil {
-				bfn.ext.ReadExt(rv2i(rvnA), bytes)
-			} else {
-				bfn.ext.UpdateExt(rv2i(rvnA), v)
-			}
-			rvn = rvnA.Elem()
-		}
-	case valueTypeNil:
-		// no-op
-	case valueTypeInt:
-		rvn = n.ri()
-	case valueTypeUint:
-		rvn = n.ru()
-	case valueTypeFloat:
-		rvn = n.rf()
-	case valueTypeBool:
-		rvn = n.rb()
-	case valueTypeString, valueTypeSymbol:
-		rvn = n.rs()
-	case valueTypeBytes:
-		rvn = n.rl()
-	case valueTypeTime:
-		rvn = n.rt()
-	default:
-		panicv.errorf("kInterfaceNaked: unexpected valueType: %d", n.v)
-	}
-	return
-}
-
-func (d *Decoder) kInterface(f *codecFnInfo, rv reflect.Value) {
-	// Note:
-	// A consequence of how kInterface works, is that
-	// if an interface already contains something, we try
-	// to decode into what was there before.
-	// We do not replace with a generic value (as got from decodeNaked).
-
-	// every interface passed here MUST be settable.
-	var rvn reflect.Value
-	if rv.IsNil() || d.h.InterfaceReset {
-		// check if mapping to a type: if so, initialize it and move on
-		rvn = d.h.intf2impl(f.ti.rtid)
-		if rvn.IsValid() {
-			rv.Set(rvn)
-		} else {
-			rvn = d.kInterfaceNaked(f)
-			if rvn.IsValid() {
-				rv.Set(rvn)
-			} else if d.h.InterfaceReset {
-				// reset to zero value based on current type in there.
-				rv.Set(reflect.Zero(rv.Elem().Type()))
-			}
-			return
-		}
-	} else {
-		// now we have a non-nil interface value, meaning it contains a type
-		rvn = rv.Elem()
-	}
-	if d.d.TryDecodeAsNil() {
-		rv.Set(reflect.Zero(rvn.Type()))
-		return
-	}
-
-	// Note: interface{} is settable, but underlying type may not be.
-	// Consequently, we MAY have to create a decodable value out of the underlying value,
-	// decode into it, and reset the interface itself.
-	// fmt.Printf(">>>> kInterface: rvn type: %v, rv type: %v\n", rvn.Type(), rv.Type())
-
-	rvn2, canDecode := isDecodeable(rvn)
-	if canDecode {
-		d.decodeValue(rvn2, nil, true)
-		return
-	}
-
-	rvn2 = reflect.New(rvn.Type()).Elem()
-	rvn2.Set(rvn)
-	d.decodeValue(rvn2, nil, true)
-	rv.Set(rvn2)
-}
-
-func decStructFieldKey(dd decDriver, keyType valueType, b *[decScratchByteArrayLen]byte) (rvkencname []byte) {
-	// use if-else-if, not switch (which compiles to binary-search)
-	// since keyType is typically valueTypeString, branch prediction is pretty good.
-
-	if keyType == valueTypeString {
-		rvkencname = dd.DecodeStringAsBytes()
-	} else if keyType == valueTypeInt {
-		rvkencname = strconv.AppendInt(b[:0], dd.DecodeInt64(), 10)
-	} else if keyType == valueTypeUint {
-		rvkencname = strconv.AppendUint(b[:0], dd.DecodeUint64(), 10)
-	} else if keyType == valueTypeFloat {
-		rvkencname = strconv.AppendFloat(b[:0], dd.DecodeFloat64(), 'f', -1, 64)
-	} else {
-		rvkencname = dd.DecodeStringAsBytes()
-	}
-	return rvkencname
-}
-
-func (d *Decoder) kStruct(f *codecFnInfo, rv reflect.Value) {
-	fti := f.ti
-	dd := d.d
-	elemsep := d.esep
-	sfn := structFieldNode{v: rv, update: true}
-	ctyp := dd.ContainerType()
-	var mf MissingFielder
-	if fti.mf {
-		mf = rv2i(rv).(MissingFielder)
-	} else if fti.mfp {
-		mf = rv2i(rv.Addr()).(MissingFielder)
-	}
-	if ctyp == valueTypeMap {
-		containerLen := dd.ReadMapStart()
-		if containerLen == 0 {
-			dd.ReadMapEnd()
-			return
-		}
-		d.depthIncr()
-		tisfi := fti.sfiSort
-		hasLen := containerLen >= 0
-
-		var rvkencname []byte
-		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-			if elemsep {
-				dd.ReadMapElemKey()
-			}
-			rvkencname = decStructFieldKey(dd, fti.keyType, &d.b)
-			if elemsep {
-				dd.ReadMapElemValue()
-			}
-			if k := fti.indexForEncName(rvkencname); k > -1 {
-				si := tisfi[k]
-				if dd.TryDecodeAsNil() {
-					si.setToZeroValue(rv)
-				} else {
-					d.decodeValue(sfn.field(si), nil, true)
-				}
-			} else if mf != nil {
-				// store rvkencname in new []byte, as it previously shares Decoder.b, which is used in decode
-				name2 := rvkencname
-				rvkencname = make([]byte, len(rvkencname))
-				copy(rvkencname, name2)
-
-				var f interface{}
-				// xdebugf("kStruct: mf != nil: before decode: rvkencname: %s", rvkencname)
-				d.decode(&f)
-				// xdebugf("kStruct: mf != nil: after decode: rvkencname: %s", rvkencname)
-				if !mf.CodecMissingField(rvkencname, f) && d.h.ErrorIfNoField {
-					d.errorf("no matching struct field found when decoding stream map with key: %s ",
-						stringView(rvkencname))
-				}
-			} else {
-				d.structFieldNotFound(-1, stringView(rvkencname))
-			}
-			// keepAlive4StringView(rvkencnameB) // not needed, as reference is outside loop
-		}
-		dd.ReadMapEnd()
-		d.depthDecr()
-	} else if ctyp == valueTypeArray {
-		containerLen := dd.ReadArrayStart()
-		if containerLen == 0 {
-			dd.ReadArrayEnd()
-			return
-		}
-		d.depthIncr()
-		// Not much gain from doing it two ways for array.
-		// Arrays are not used as much for structs.
-		hasLen := containerLen >= 0
-		var checkbreak bool
-		for j, si := range fti.sfiSrc {
-			if hasLen && j == containerLen {
-				break
-			}
-			if !hasLen && dd.CheckBreak() {
-				checkbreak = true
-				break
-			}
-			if elemsep {
-				dd.ReadArrayElem()
-			}
-			if dd.TryDecodeAsNil() {
-				si.setToZeroValue(rv)
-			} else {
-				d.decodeValue(sfn.field(si), nil, true)
-			}
-		}
-		if (hasLen && containerLen > len(fti.sfiSrc)) || (!hasLen && !checkbreak) {
-			// read remaining values and throw away
-			for j := len(fti.sfiSrc); ; j++ {
-				if (hasLen && j == containerLen) || (!hasLen && dd.CheckBreak()) {
-					break
-				}
-				if elemsep {
-					dd.ReadArrayElem()
-				}
-				d.structFieldNotFound(j, "")
-			}
-		}
-		dd.ReadArrayEnd()
-		d.depthDecr()
-	} else {
-		d.errorstr(errstrOnlyMapOrArrayCanDecodeIntoStruct)
-		return
-	}
-}
-
-func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
-	// A slice can be set from a map or array in stream.
-	// This way, the order can be kept (as order is lost with map).
-	ti := f.ti
-	if f.seq == seqTypeChan && ti.chandir&uint8(reflect.SendDir) == 0 {
-		d.errorf("receive-only channel cannot be decoded")
-	}
-	dd := d.d
-	rtelem0 := ti.elem
-	ctyp := dd.ContainerType()
-	if ctyp == valueTypeBytes || ctyp == valueTypeString {
-		// you can only decode bytes or string in the stream into a slice or array of bytes
-		if !(ti.rtid == uint8SliceTypId || rtelem0.Kind() == reflect.Uint8) {
-			d.errorf("bytes/string in stream must decode into slice/array of bytes, not %v", ti.rt)
-		}
-		if f.seq == seqTypeChan {
-			bs2 := dd.DecodeBytes(nil, true)
-			irv := rv2i(rv)
-			ch, ok := irv.(chan<- byte)
-			if !ok {
-				ch = irv.(chan byte)
-			}
-			for _, b := range bs2 {
-				ch <- b
-			}
-		} else {
-			rvbs := rv.Bytes()
-			bs2 := dd.DecodeBytes(rvbs, false)
-			// if rvbs == nil && bs2 != nil || rvbs != nil && bs2 == nil || len(bs2) != len(rvbs) {
-			if !(len(bs2) > 0 && len(bs2) == len(rvbs) && &bs2[0] == &rvbs[0]) {
-				if rv.CanSet() {
-					rv.SetBytes(bs2)
-				} else if len(rvbs) > 0 && len(bs2) > 0 {
-					copy(rvbs, bs2)
-				}
-			}
-		}
-		return
-	}
-
-	// array := f.seq == seqTypeChan
-
-	slh, containerLenS := d.decSliceHelperStart() // only expects valueType(Array|Map)
-
-	// an array can never return a nil slice. so no need to check f.array here.
-	if containerLenS == 0 {
-		if rv.CanSet() {
-			if f.seq == seqTypeSlice {
-				if rv.IsNil() {
-					rv.Set(reflect.MakeSlice(ti.rt, 0, 0))
-				} else {
-					rv.SetLen(0)
-				}
-			} else if f.seq == seqTypeChan {
-				if rv.IsNil() {
-					rv.Set(reflect.MakeChan(ti.rt, 0))
-				}
-			}
-		}
-		slh.End()
-		return
-	}
-
-	d.depthIncr()
-
-	rtelem0Size := int(rtelem0.Size())
-	rtElem0Kind := rtelem0.Kind()
-	rtelem0Mut := !isImmutableKind(rtElem0Kind)
-	rtelem := rtelem0
-	rtelemkind := rtelem.Kind()
-	for rtelemkind == reflect.Ptr {
-		rtelem = rtelem.Elem()
-		rtelemkind = rtelem.Kind()
-	}
-
-	var fn *codecFn
-
-	var rvCanset = rv.CanSet()
-	var rvChanged bool
-	var rv0 = rv
-	var rv9 reflect.Value
-
-	rvlen := rv.Len()
-	rvcap := rv.Cap()
-	hasLen := containerLenS > 0
-	if hasLen && f.seq == seqTypeSlice {
-		if containerLenS > rvcap {
-			oldRvlenGtZero := rvlen > 0
-			rvlen = decInferLen(containerLenS, d.h.MaxInitLen, int(rtelem0.Size()))
-			if rvlen <= rvcap {
-				if rvCanset {
-					rv.SetLen(rvlen)
-				}
-			} else if rvCanset {
-				rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
-				rvcap = rvlen
-				rvChanged = true
-			} else {
-				d.errorf("cannot decode into non-settable slice")
-			}
-			if rvChanged && oldRvlenGtZero && !isImmutableKind(rtelem0.Kind()) {
-				reflect.Copy(rv, rv0) // only copy up to length NOT cap i.e. rv0.Slice(0, rvcap)
-			}
-		} else if containerLenS != rvlen {
-			rvlen = containerLenS
-			if rvCanset {
-				rv.SetLen(rvlen)
-			}
-			// else {
-			// rv = rv.Slice(0, rvlen)
-			// rvChanged = true
-			// d.errorf("cannot decode into non-settable slice")
-			// }
-		}
-	}
-
-	// consider creating new element once, and just decoding into it.
-	var rtelem0Zero reflect.Value
-	var rtelem0ZeroValid bool
-	var decodeAsNil bool
-	var j int
-
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && (f.seq == seqTypeSlice || f.seq == seqTypeChan) && rv.IsNil() {
-			if hasLen {
-				rvlen = decInferLen(containerLenS, d.h.MaxInitLen, rtelem0Size)
-			} else if f.seq == seqTypeSlice {
-				rvlen = decDefSliceCap
-			} else {
-				rvlen = decDefChanCap
-			}
-			if rvCanset {
-				if f.seq == seqTypeSlice {
-					rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
-					rvChanged = true
-				} else { // chan
-					rv = reflect.MakeChan(ti.rt, rvlen)
-					rvChanged = true
-				}
-			} else {
-				d.errorf("cannot decode into non-settable slice")
-			}
-		}
-		slh.ElemContainerState(j)
-		decodeAsNil = dd.TryDecodeAsNil()
-		if f.seq == seqTypeChan {
-			if decodeAsNil {
-				rv.Send(reflect.Zero(rtelem0))
-				continue
-			}
-			if rtelem0Mut || !rv9.IsValid() { // || (rtElem0Kind == reflect.Ptr && rv9.IsNil()) {
-				rv9 = reflect.New(rtelem0).Elem()
-			}
-			if fn == nil {
-				fn = d.h.fn(rtelem, true, true)
-			}
-			d.decodeValue(rv9, fn, true)
-			rv.Send(rv9)
-		} else {
-			// if indefinite, etc, then expand the slice if necessary
-			var decodeIntoBlank bool
-			if j >= rvlen {
-				if f.seq == seqTypeArray {
-					d.arrayCannotExpand(rvlen, j+1)
-					decodeIntoBlank = true
-				} else { // if f.seq == seqTypeSlice
-					// rv = reflect.Append(rv, reflect.Zero(rtelem0)) // append logic + varargs
-					var rvcap2 int
-					var rvErrmsg2 string
-					rv9, rvcap2, rvChanged, rvErrmsg2 =
-						expandSliceRV(rv, ti.rt, rvCanset, rtelem0Size, 1, rvlen, rvcap)
-					if rvErrmsg2 != "" {
-						d.errorf(rvErrmsg2)
-					}
-					rvlen++
-					if rvChanged {
-						rv = rv9
-						rvcap = rvcap2
-					}
-				}
-			}
-			if decodeIntoBlank {
-				if !decodeAsNil {
-					d.swallow()
-				}
-			} else {
-				rv9 = rv.Index(j)
-				if d.h.SliceElementReset || decodeAsNil {
-					if !rtelem0ZeroValid {
-						rtelem0ZeroValid = true
-						rtelem0Zero = reflect.Zero(rtelem0)
-					}
-					rv9.Set(rtelem0Zero)
-					if decodeAsNil {
-						continue
-					}
-				}
-
-				if fn == nil {
-					fn = d.h.fn(rtelem, true, true)
-				}
-				d.decodeValue(rv9, fn, true)
-			}
-		}
-	}
-	if f.seq == seqTypeSlice {
-		if j < rvlen {
-			if rv.CanSet() {
-				rv.SetLen(j)
-			} else if rvCanset {
-				rv = rv.Slice(0, j)
-				rvChanged = true
-			} // else { d.errorf("kSlice: cannot change non-settable slice") }
-			rvlen = j
-		} else if j == 0 && rv.IsNil() {
-			if rvCanset {
-				rv = reflect.MakeSlice(ti.rt, 0, 0)
-				rvChanged = true
-			} // else { d.errorf("kSlice: cannot change non-settable slice") }
-		}
-	}
-	slh.End()
-
-	if rvChanged { // infers rvCanset=true, so it can be reset
-		rv0.Set(rv)
-	}
-
-	d.depthDecr()
-}
-
-// func (d *Decoder) kArray(f *codecFnInfo, rv reflect.Value) {
-// 	// d.decodeValueFn(rv.Slice(0, rv.Len()))
-// 	f.kSlice(rv.Slice(0, rv.Len()))
-// }
-
-func (d *Decoder) kMap(f *codecFnInfo, rv reflect.Value) {
-	dd := d.d
-	containerLen := dd.ReadMapStart()
-	elemsep := d.esep
-	ti := f.ti
-	if rv.IsNil() {
-		rvlen := decInferLen(containerLen, d.h.MaxInitLen, int(ti.key.Size()+ti.elem.Size()))
-		rv.Set(makeMapReflect(ti.rt, rvlen))
-	}
-
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return
-	}
-
-	d.depthIncr()
-
-	ktype, vtype := ti.key, ti.elem
-	ktypeId := rt2id(ktype)
-	vtypeKind := vtype.Kind()
-
-	var keyFn, valFn *codecFn
-	var ktypeLo, vtypeLo reflect.Type
-
-	for ktypeLo = ktype; ktypeLo.Kind() == reflect.Ptr; ktypeLo = ktypeLo.Elem() {
-	}
-
-	for vtypeLo = vtype; vtypeLo.Kind() == reflect.Ptr; vtypeLo = vtypeLo.Elem() {
-	}
-
-	var mapGet, mapSet bool
-	rvvImmut := isImmutableKind(vtypeKind)
-	if !d.h.MapValueReset {
-		// if pointer, mapGet = true
-		// if interface, mapGet = true if !DecodeNakedAlways (else false)
-		// if builtin, mapGet = false
-		// else mapGet = true
-		if vtypeKind == reflect.Ptr {
-			mapGet = true
-		} else if vtypeKind == reflect.Interface {
-			if !d.h.InterfaceReset {
-				mapGet = true
-			}
-		} else if !rvvImmut {
-			mapGet = true
-		}
-	}
-
-	var rvk, rvkp, rvv, rvz reflect.Value
-	rvkMut := !isImmutableKind(ktype.Kind()) // if ktype is immutable, then re-use the same rvk.
-	ktypeIsString := ktypeId == stringTypId
-	ktypeIsIntf := ktypeId == intfTypId
-	hasLen := containerLen > 0
-	var kstrbs []byte
-
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if rvkMut || !rvkp.IsValid() {
-			rvkp = reflect.New(ktype)
-			rvk = rvkp.Elem()
-		}
-		if elemsep {
-			dd.ReadMapElemKey()
-		}
-		// if false && dd.TryDecodeAsNil() { // nil cannot be a map key, so disregard this block
-		// 	// Previously, if a nil key, we just ignored the mapped value and continued.
-		// 	// However, that makes the result of encoding and then decoding map[intf]intf{nil:nil}
-		// 	// to be an empty map.
-		// 	// Instead, we treat a nil key as the zero value of the type.
-		// 	rvk.Set(reflect.Zero(ktype))
-		// } else if ktypeIsString {
-		if ktypeIsString {
-			kstrbs = dd.DecodeStringAsBytes()
-			rvk.SetString(stringView(kstrbs))
-			// NOTE: if doing an insert, you MUST use a real string (not stringview)
-		} else {
-			if keyFn == nil {
-				keyFn = d.h.fn(ktypeLo, true, true)
-			}
-			d.decodeValue(rvk, keyFn, true)
-		}
-		// special case if a byte array.
-		if ktypeIsIntf {
-			if rvk2 := rvk.Elem(); rvk2.IsValid() {
-				if rvk2.Type() == uint8SliceTyp {
-					rvk = reflect.ValueOf(d.string(rvk2.Bytes()))
-				} else {
-					rvk = rvk2
-				}
-			}
-		}
-
-		if elemsep {
-			dd.ReadMapElemValue()
-		}
-
-		// Brittle, but OK per TryDecodeAsNil() contract.
-		// i.e. TryDecodeAsNil never shares slices with other decDriver procedures
-		if dd.TryDecodeAsNil() {
-			if ktypeIsString {
-				rvk.SetString(d.string(kstrbs))
-			}
-			if d.h.DeleteOnNilMapValue {
-				rv.SetMapIndex(rvk, reflect.Value{})
-			} else {
-				rv.SetMapIndex(rvk, reflect.Zero(vtype))
-			}
-			continue
-		}
-
-		mapSet = true // set to false if u do a get, and its a non-nil pointer
-		if mapGet {
-			// mapGet true only in case where kind=Ptr|Interface or kind is otherwise mutable.
-			rvv = rv.MapIndex(rvk)
-			if !rvv.IsValid() {
-				rvv = reflect.New(vtype).Elem()
-			} else if vtypeKind == reflect.Ptr {
-				if rvv.IsNil() {
-					rvv = reflect.New(vtype).Elem()
-				} else {
-					mapSet = false
-				}
-			} else if vtypeKind == reflect.Interface {
-				// not addressable, and thus not settable.
-				// e MUST create a settable/addressable variant
-				rvv2 := reflect.New(rvv.Type()).Elem()
-				if !rvv.IsNil() {
-					rvv2.Set(rvv)
-				}
-				rvv = rvv2
-			}
-			// else it is ~mutable, and we can just decode into it directly
-		} else if rvvImmut {
-			if !rvz.IsValid() {
-				rvz = reflect.New(vtype).Elem()
-			}
-			rvv = rvz
-		} else {
-			rvv = reflect.New(vtype).Elem()
-		}
-
-		// We MUST be done with the stringview of the key, before decoding the value
-		// so that we don't bastardize the reused byte array.
-		if mapSet && ktypeIsString {
-			rvk.SetString(d.string(kstrbs))
-		}
-		if valFn == nil {
-			valFn = d.h.fn(vtypeLo, true, true)
-		}
-		d.decodeValue(rvv, valFn, true)
-		// d.decodeValueFn(rvv, valFn)
-		if mapSet {
-			rv.SetMapIndex(rvk, rvv)
-		}
-		// if ktypeIsString {
-		// 	// keepAlive4StringView(kstrbs) // not needed, as reference is outside loop
-		// }
-	}
-
-	dd.ReadMapEnd()
-
-	d.depthDecr()
-}
-
-// decNaked is used to keep track of the primitives decoded.
-// Without it, we would have to decode each primitive and wrap it
-// in an interface{}, causing an allocation.
-// In this model, the primitives are decoded in a "pseudo-atomic" fashion,
-// so we can rest assured that no other decoding happens while these
-// primitives are being decoded.
-//
-// maps and arrays are not handled by this mechanism.
-// However, RawExt is, and we accommodate for extensions that decode
-// RawExt from DecodeNaked, but need to decode the value subsequently.
-// kInterfaceNaked and swallow, which call DecodeNaked, handle this caveat.
-//
-// However, decNaked also keeps some arrays of default maps and slices
-// used in DecodeNaked. This way, we can get a pointer to it
-// without causing a new heap allocation.
-//
-// kInterfaceNaked will ensure that there is no allocation for the common
-// uses.
-
-type decNaked struct {
-	// r RawExt // used for RawExt, uint, []byte.
-
-	// primitives below
-	u uint64
-	i int64
-	f float64
-	l []byte
-	s string
-
-	// ---- cpu cache line boundary?
-	t time.Time
-	b bool
-
-	// state
-	v valueType
-	_ [6]bool // padding
-
-	// ru, ri, rf, rl, rs, rb, rt reflect.Value // mapping to the primitives above
-	//
-	// _ [3]uint64 // padding
-}
-
-// func (n *decNaked) init() {
-// 	n.ru = reflect.ValueOf(&n.u).Elem()
-// 	n.ri = reflect.ValueOf(&n.i).Elem()
-// 	n.rf = reflect.ValueOf(&n.f).Elem()
-// 	n.rl = reflect.ValueOf(&n.l).Elem()
-// 	n.rs = reflect.ValueOf(&n.s).Elem()
-// 	n.rt = reflect.ValueOf(&n.t).Elem()
-// 	n.rb = reflect.ValueOf(&n.b).Elem()
-// 	// n.rr[] = reflect.ValueOf(&n.)
-// }
-
-// type decNakedPooler struct {
-// 	n   *decNaked
-// 	nsp *sync.Pool
-// }
-
-// // naked must be called before each call to .DecodeNaked, as they will use it.
-// func (d *decNakedPooler) naked() *decNaked {
-// 	if d.n == nil {
-// 		// consider one of:
-// 		//   - get from sync.Pool  (if GC is frequent, there's no value here)
-// 		//   - new alloc           (safest. only init'ed if it a naked decode will be done)
-// 		//   - field in Decoder    (makes the Decoder struct very big)
-// 		// To support using a decoder where a DecodeNaked is not needed,
-// 		// we prefer #1 or #2.
-// 		// d.n = new(decNaked) // &d.nv // new(decNaked) // grab from a sync.Pool
-// 		// d.n.init()
-// 		var v interface{}
-// 		d.nsp, v = pool.decNaked()
-// 		d.n = v.(*decNaked)
-// 	}
-// 	return d.n
-// }
-
-// func (d *decNakedPooler) end() {
-// 	if d.n != nil {
-// 		// if n != nil, then nsp != nil (they are always set together)
-// 		d.nsp.Put(d.n)
-// 		d.n, d.nsp = nil, nil
-// 	}
-// }
-
-// type rtid2rv struct {
-// 	rtid uintptr
-// 	rv   reflect.Value
-// }
-
-// --------------
-
-type decReaderSwitch struct {
-	rb bytesDecReader
-	// ---- cpu cache line boundary?
-	ri *ioDecReader
-	bi *bufioDecReader
-
-	mtr, str bool // whether maptype or slicetype are known types
-
-	be   bool // is binary encoding
-	js   bool // is json handle
-	jsms bool // is json handle, and MapKeyAsString
-	esep bool // has elem separators
-
-	// typ   entryType
-	bytes bool // is bytes reader
-	bufio bool // is this a bufioDecReader?
-}
-
-// numread, track and stopTrack are always inlined, as they just check int fields, etc.
-
-/*
-func (z *decReaderSwitch) numread() int {
-	switch z.typ {
-	case entryTypeBytes:
-		return z.rb.numread()
-	case entryTypeIo:
-		return z.ri.numread()
-	default:
-		return z.bi.numread()
-	}
-}
-func (z *decReaderSwitch) track() {
-	switch z.typ {
-	case entryTypeBytes:
-		z.rb.track()
-	case entryTypeIo:
-		z.ri.track()
-	default:
-		z.bi.track()
-	}
-}
-func (z *decReaderSwitch) stopTrack() []byte {
-	switch z.typ {
-	case entryTypeBytes:
-		return z.rb.stopTrack()
-	case entryTypeIo:
-		return z.ri.stopTrack()
-	default:
-		return z.bi.stopTrack()
-	}
-}
-
-func (z *decReaderSwitch) unreadn1() {
-	switch z.typ {
-	case entryTypeBytes:
-		z.rb.unreadn1()
-	case entryTypeIo:
-		z.ri.unreadn1()
-	default:
-		z.bi.unreadn1()
-	}
-}
-func (z *decReaderSwitch) readx(n int) []byte {
-	switch z.typ {
-	case entryTypeBytes:
-		return z.rb.readx(n)
-	case entryTypeIo:
-		return z.ri.readx(n)
-	default:
-		return z.bi.readx(n)
-	}
-}
-func (z *decReaderSwitch) readb(s []byte) {
-	switch z.typ {
-	case entryTypeBytes:
-		z.rb.readb(s)
-	case entryTypeIo:
-		z.ri.readb(s)
-	default:
-		z.bi.readb(s)
-	}
-}
-func (z *decReaderSwitch) readn1() uint8 {
-	switch z.typ {
-	case entryTypeBytes:
-		return z.rb.readn1()
-	case entryTypeIo:
-		return z.ri.readn1()
-	default:
-		return z.bi.readn1()
-	}
-}
-func (z *decReaderSwitch) skip(accept *bitset256) (token byte) {
-	switch z.typ {
-	case entryTypeBytes:
-		return z.rb.skip(accept)
-	case entryTypeIo:
-		return z.ri.skip(accept)
-	default:
-		return z.bi.skip(accept)
-	}
-}
-func (z *decReaderSwitch) readTo(in []byte, accept *bitset256) (out []byte) {
-	switch z.typ {
-	case entryTypeBytes:
-		return z.rb.readTo(in, accept)
-	case entryTypeIo:
-		return z.ri.readTo(in, accept)
-	default:
-		return z.bi.readTo(in, accept)
-	}
-}
-func (z *decReaderSwitch) readUntil(in []byte, stop byte) (out []byte) {
-	switch z.typ {
-	case entryTypeBytes:
-		return z.rb.readUntil(in, stop)
-	case entryTypeIo:
-		return z.ri.readUntil(in, stop)
-	default:
-		return z.bi.readUntil(in, stop)
-	}
-}
-
-*/
-
-// the if/else-if/else block is expensive to inline.
-// Each node of this construct costs a lot and dominates the budget.
-// Best to only do an if fast-path else block (so fast-path is inlined).
-// This is irrespective of inlineExtraCallCost set in $GOROOT/src/cmd/compile/internal/gc/inl.go
-//
-// In decReaderSwitch methods below, we delegate all IO functions into their own methods.
-// This allows for the inlining of the common path when z.bytes=true.
-// Go 1.12+ supports inlining methods with up to 1 inlined function (or 2 if no other constructs).
-
-func (z *decReaderSwitch) numread() uint {
-	if z.bytes {
-		return z.rb.numread()
-	} else if z.bufio {
-		return z.bi.numread()
-	} else {
-		return z.ri.numread()
-	}
-}
-func (z *decReaderSwitch) track() {
-	if z.bytes {
-		z.rb.track()
-	} else if z.bufio {
-		z.bi.track()
-	} else {
-		z.ri.track()
-	}
-}
-func (z *decReaderSwitch) stopTrack() []byte {
-	if z.bytes {
-		return z.rb.stopTrack()
-	} else if z.bufio {
-		return z.bi.stopTrack()
-	} else {
-		return z.ri.stopTrack()
-	}
-}
-
-// func (z *decReaderSwitch) unreadn1() {
-// 	if z.bytes {
-// 		z.rb.unreadn1()
-// 	} else {
-// 		z.unreadn1IO()
-// 	}
-// }
-// func (z *decReaderSwitch) unreadn1IO() {
-// 	if z.bufio {
-// 		z.bi.unreadn1()
-// 	} else {
-// 		z.ri.unreadn1()
-// 	}
-// }
-
-func (z *decReaderSwitch) unreadn1() {
-	if z.bytes {
-		z.rb.unreadn1()
-	} else if z.bufio {
-		z.bi.unreadn1()
-	} else {
-		z.ri.unreadn1() // not inlined
-	}
-}
-
-func (z *decReaderSwitch) readx(n uint) []byte {
-	if z.bytes {
-		return z.rb.readx(n)
-	}
-	return z.readxIO(n)
-}
-func (z *decReaderSwitch) readxIO(n uint) []byte {
-	if z.bufio {
-		return z.bi.readx(n)
-	}
-	return z.ri.readx(n)
-}
-
-func (z *decReaderSwitch) readb(s []byte) {
-	if z.bytes {
-		z.rb.readb(s)
-	} else {
-		z.readbIO(s)
-	}
-}
-
-//go:noinline - fallback for io, ensures z.bytes path is inlined
-func (z *decReaderSwitch) readbIO(s []byte) {
-	if z.bufio {
-		z.bi.readb(s)
-	} else {
-		z.ri.readb(s)
-	}
-}
-
-func (z *decReaderSwitch) readn1() uint8 {
-	if z.bytes {
-		return z.rb.readn1()
-	}
-	return z.readn1IO()
-}
-func (z *decReaderSwitch) readn1IO() uint8 {
-	if z.bufio {
-		return z.bi.readn1()
-	}
-	return z.ri.readn1()
-}
-
-func (z *decReaderSwitch) skip(accept *bitset256) (token byte) {
-	if z.bytes {
-		return z.rb.skip(accept)
-	}
-	return z.skipIO(accept)
-}
-func (z *decReaderSwitch) skipIO(accept *bitset256) (token byte) {
-	if z.bufio {
-		return z.bi.skip(accept)
-	}
-	return z.ri.skip(accept)
-}
-
-func (z *decReaderSwitch) readTo(in []byte, accept *bitset256) (out []byte) {
-	if z.bytes {
-		return z.rb.readToNoInput(accept) // z.rb.readTo(in, accept)
-	}
-	return z.readToIO(in, accept)
-}
-
-//go:noinline - fallback for io, ensures z.bytes path is inlined
-func (z *decReaderSwitch) readToIO(in []byte, accept *bitset256) (out []byte) {
-	if z.bufio {
-		return z.bi.readTo(in, accept)
-	}
-	return z.ri.readTo(in, accept)
-}
-func (z *decReaderSwitch) readUntil(in []byte, stop byte) (out []byte) {
-	if z.bytes {
-		return z.rb.readUntilNoInput(stop)
-	}
-	return z.readUntilIO(in, stop)
-}
-
-func (z *decReaderSwitch) readUntilIO(in []byte, stop byte) (out []byte) {
-	if z.bufio {
-		return z.bi.readUntil(in, stop)
-	}
-	return z.ri.readUntil(in, stop)
-}
-
-// Decoder reads and decodes an object from an input stream in a supported format.
-//
-// Decoder is NOT safe for concurrent use i.e. a Decoder cannot be used
-// concurrently in multiple goroutines.
-//
-// However, as Decoder could be allocation heavy to initialize, a Reset method is provided
-// so its state can be reused to decode new input streams repeatedly.
-// This is the idiomatic way to use.
-type Decoder struct {
-	panicHdl
-	// hopefully, reduce derefencing cost by laying the decReader inside the Decoder.
-	// Try to put things that go together to fit within a cache line (8 words).
-
-	d decDriver
-
-	// NOTE: Decoder shouldn't call it's read methods,
-	// as the handler MAY need to do some coordination.
-	r *decReaderSwitch
-
-	// bi *bufioDecReader
-	// cache the mapTypeId and sliceTypeId for faster comparisons
-	mtid uintptr
-	stid uintptr
-
-	hh Handle
-	h  *BasicHandle
-
-	// ---- cpu cache line boundary?
-	decReaderSwitch
-
-	// ---- cpu cache line boundary?
-	n decNaked
-
-	// cr containerStateRecv
-	err error
-
-	depth    int16
-	maxdepth int16
-
-	_ [4]uint8 // padding
-
-	is map[string]string // used for interning strings
-
-	// ---- cpu cache line boundary?
-	b [decScratchByteArrayLen]byte // scratch buffer, used by Decoder and xxxEncDrivers
-
-	// padding - false sharing help // modify 232 if Decoder struct changes.
-	// _ [cacheLineSize - 232%cacheLineSize]byte
-}
-
-// NewDecoder returns a Decoder for decoding a stream of bytes from an io.Reader.
-//
-// For efficiency, Users are encouraged to configure ReaderBufferSize on the handle
-// OR pass in a memory buffered reader (eg bufio.Reader, bytes.Buffer).
-func NewDecoder(r io.Reader, h Handle) *Decoder {
-	d := newDecoder(h)
-	d.Reset(r)
-	return d
-}
-
-// NewDecoderBytes returns a Decoder which efficiently decodes directly
-// from a byte slice with zero copying.
-func NewDecoderBytes(in []byte, h Handle) *Decoder {
-	d := newDecoder(h)
-	d.ResetBytes(in)
-	return d
-}
-
-// var defaultDecNaked decNaked
-
-func newDecoder(h Handle) *Decoder {
-	d := &Decoder{h: basicHandle(h), err: errDecoderNotInitialized}
-	d.bytes = true
-	if useFinalizers {
-		runtime.SetFinalizer(d, (*Decoder).finalize)
-		// xdebugf(">>>> new(Decoder) with finalizer")
-	}
-	d.r = &d.decReaderSwitch
-	d.hh = h
-	d.be = h.isBinary()
-	// NOTE: do not initialize d.n here. It is lazily initialized in d.naked()
-	var jh *JsonHandle
-	jh, d.js = h.(*JsonHandle)
-	if d.js {
-		d.jsms = jh.MapKeyAsString
-	}
-	d.esep = d.hh.hasElemSeparators()
-	if d.h.InternString {
-		d.is = make(map[string]string, 32)
-	}
-	d.d = h.newDecDriver(d)
-	// d.cr, _ = d.d.(containerStateRecv)
-	return d
-}
-
-func (d *Decoder) resetCommon() {
-	// d.r = &d.decReaderSwitch
-	d.d.reset()
-	d.err = nil
-	d.depth = 0
-	d.maxdepth = d.h.MaxDepth
-	if d.maxdepth <= 0 {
-		d.maxdepth = decDefMaxDepth
-	}
-	// reset all things which were cached from the Handle, but could change
-	d.mtid, d.stid = 0, 0
-	d.mtr, d.str = false, false
-	if d.h.MapType != nil {
-		d.mtid = rt2id(d.h.MapType)
-		d.mtr = fastpathAV.index(d.mtid) != -1
-	}
-	if d.h.SliceType != nil {
-		d.stid = rt2id(d.h.SliceType)
-		d.str = fastpathAV.index(d.stid) != -1
-	}
-}
-
-// Reset the Decoder with a new Reader to decode from,
-// clearing all state from last run(s).
-func (d *Decoder) Reset(r io.Reader) {
-	if r == nil {
-		return
-	}
-	d.bytes = false
-	// d.typ = entryTypeUnset
-	if d.h.ReaderBufferSize > 0 {
-		if d.bi == nil {
-			d.bi = new(bufioDecReader)
-		}
-		d.bi.reset(r, d.h.ReaderBufferSize)
-		// d.r = d.bi
-		// d.typ = entryTypeBufio
-		d.bufio = true
-	} else {
-		// d.ri.x = &d.b
-		// d.s = d.sa[:0]
-		if d.ri == nil {
-			d.ri = new(ioDecReader)
-		}
-		d.ri.reset(r)
-		// d.r = d.ri
-		// d.typ = entryTypeIo
-		d.bufio = false
-	}
-	d.resetCommon()
-}
-
-// ResetBytes resets the Decoder with a new []byte to decode from,
-// clearing all state from last run(s).
-func (d *Decoder) ResetBytes(in []byte) {
-	if in == nil {
-		return
-	}
-	d.bytes = true
-	d.bufio = false
-	// d.typ = entryTypeBytes
-	d.rb.reset(in)
-	// d.r = &d.rb
-	d.resetCommon()
-}
-
-func (d *Decoder) naked() *decNaked {
-	return &d.n
-}
-
-// Decode decodes the stream from reader and stores the result in the
-// value pointed to by v. v cannot be a nil pointer. v can also be
-// a reflect.Value of a pointer.
-//
-// Note that a pointer to a nil interface is not a nil pointer.
-// If you do not know what type of stream it is, pass in a pointer to a nil interface.
-// We will decode and store a value in that nil interface.
-//
-// Sample usages:
-//   // Decoding into a non-nil typed value
-//   var f float32
-//   err = codec.NewDecoder(r, handle).Decode(&f)
-//
-//   // Decoding into nil interface
-//   var v interface{}
-//   dec := codec.NewDecoder(r, handle)
-//   err = dec.Decode(&v)
-//
-// When decoding into a nil interface{}, we will decode into an appropriate value based
-// on the contents of the stream:
-//   - Numbers are decoded as float64, int64 or uint64.
-//   - Other values are decoded appropriately depending on the type:
-//     bool, string, []byte, time.Time, etc
-//   - Extensions are decoded as RawExt (if no ext function registered for the tag)
-// Configurations exist on the Handle to override defaults
-// (e.g. for MapType, SliceType and how to decode raw bytes).
-//
-// When decoding into a non-nil interface{} value, the mode of encoding is based on the
-// type of the value. When a value is seen:
-//   - If an extension is registered for it, call that extension function
-//   - If it implements BinaryUnmarshaler, call its UnmarshalBinary(data []byte) error
-//   - Else decode it based on its reflect.Kind
-//
-// There are some special rules when decoding into containers (slice/array/map/struct).
-// Decode will typically use the stream contents to UPDATE the container i.e. the values
-// in these containers will not be zero'ed before decoding.
-//   - A map can be decoded from a stream map, by updating matching keys.
-//   - A slice can be decoded from a stream array,
-//     by updating the first n elements, where n is length of the stream.
-//   - A slice can be decoded from a stream map, by decoding as if
-//     it contains a sequence of key-value pairs.
-//   - A struct can be decoded from a stream map, by updating matching fields.
-//   - A struct can be decoded from a stream array,
-//     by updating fields as they occur in the struct (by index).
-//
-// This in-place update maintains consistency in the decoding philosophy (i.e. we ALWAYS update
-// in place by default). However, the consequence of this is that values in slices or maps
-// which are not zero'ed before hand, will have part of the prior values in place after decode
-// if the stream doesn't contain an update for those parts.
-//
-// This in-place update can be disabled by configuring the MapValueReset and SliceElementReset
-// decode options available on every handle.
-//
-// Furthermore, when decoding a stream map or array with length of 0 into a nil map or slice,
-// we reset the destination map or slice to a zero-length value.
-//
-// However, when decoding a stream nil, we reset the destination container
-// to its "zero" value (e.g. nil for slice/map, etc).
-//
-// Note: we allow nil values in the stream anywhere except for map keys.
-// A nil value in the encoded stream where a map key is expected is treated as an error.
-func (d *Decoder) Decode(v interface{}) (err error) {
-	// tried to use closure, as runtime optimizes defer with no params.
-	// This seemed to be causing weird issues (like circular reference found, unexpected panic, etc).
-	// Also, see https://github.com/golang/go/issues/14939#issuecomment-417836139
-	// defer func() { d.deferred(&err) }()
-	// { x, y := d, &err; defer func() { x.deferred(y) }() }
-	if d.err != nil {
-		return d.err
-	}
-	if recoverPanicToErr {
-		defer func() {
-			if x := recover(); x != nil {
-				panicValToErr(d, x, &d.err)
-				err = d.err
-			}
-		}()
-	}
-
-	// defer d.deferred(&err)
-	d.mustDecode(v)
-	return
-}
-
-// MustDecode is like Decode, but panics if unable to Decode.
-// This provides insight to the code location that triggered the error.
-func (d *Decoder) MustDecode(v interface{}) {
-	if d.err != nil {
-		panic(d.err)
-	}
-	d.mustDecode(v)
-}
-
-// MustDecode is like Decode, but panics if unable to Decode.
-// This provides insight to the code location that triggered the error.
-func (d *Decoder) mustDecode(v interface{}) {
-	// TODO: Top-level: ensure that v is a pointer and not nil.
-	if d.d.TryDecodeAsNil() {
-		setZero(v)
-		return
-	}
-	if d.bi == nil {
-		d.decode(v)
-		return
-	}
-
-	d.bi.calls++
-	d.decode(v)
-	// xprintf(">>>>>>>> >>>>>>>> num decFns: %v\n", d.cf.sn)
-	d.bi.calls--
-	if !d.h.ExplicitRelease && d.bi.calls == 0 {
-		d.bi.release()
-	}
-}
-
-// func (d *Decoder) deferred(err1 *error) {
-// 	if recoverPanicToErr {
-// 		if x := recover(); x != nil {
-// 			panicValToErr(d, x, err1)
-// 			panicValToErr(d, x, &d.err)
-// 		}
-// 	}
-// }
-
-//go:noinline -- as it is run by finalizer
-func (d *Decoder) finalize() {
-	// xdebugf("finalizing Decoder")
-	d.Release()
-}
-
-// Release releases shared (pooled) resources.
-//
-// It is important to call Release() when done with a Decoder, so those resources
-// are released instantly for use by subsequently created Decoders.
-//
-// By default, Release() is automatically called unless the option ExplicitRelease is set.
-func (d *Decoder) Release() {
-	if d.bi != nil {
-		d.bi.release()
-	}
-	// d.decNakedPooler.end()
-}
-
-// // this is not a smart swallow, as it allocates objects and does unnecessary work.
-// func (d *Decoder) swallowViaHammer() {
-// 	var blank interface{}
-// 	d.decodeValueNoFn(reflect.ValueOf(&blank).Elem())
-// }
-
-func (d *Decoder) swallow() {
-	// smarter decode that just swallows the content
-	dd := d.d
-	if dd.TryDecodeAsNil() {
-		return
-	}
-	elemsep := d.esep
-	switch dd.ContainerType() {
-	case valueTypeMap:
-		containerLen := dd.ReadMapStart()
-		d.depthIncr()
-		hasLen := containerLen >= 0
-		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-			// if clenGtEqualZero {if j >= containerLen {break} } else if dd.CheckBreak() {break}
-			if elemsep {
-				dd.ReadMapElemKey()
-			}
-			d.swallow()
-			if elemsep {
-				dd.ReadMapElemValue()
-			}
-			d.swallow()
-		}
-		dd.ReadMapEnd()
-		d.depthDecr()
-	case valueTypeArray:
-		containerLen := dd.ReadArrayStart()
-		d.depthIncr()
-		hasLen := containerLen >= 0
-		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-			if elemsep {
-				dd.ReadArrayElem()
-			}
-			d.swallow()
-		}
-		dd.ReadArrayEnd()
-		d.depthDecr()
-	case valueTypeBytes:
-		dd.DecodeBytes(d.b[:], true)
-	case valueTypeString:
-		dd.DecodeStringAsBytes()
-	default:
-		// these are all primitives, which we can get from decodeNaked
-		// if RawExt using Value, complete the processing.
-		n := d.naked()
-		dd.DecodeNaked()
-		if n.v == valueTypeExt && n.l == nil {
-			var v2 interface{}
-			d.decode(&v2)
-		}
-	}
-}
-
-func setZero(iv interface{}) {
-	if iv == nil || definitelyNil(iv) {
-		return
-	}
-	var canDecode bool
-	switch v := iv.(type) {
-	case *string:
-		*v = ""
-	case *bool:
-		*v = false
-	case *int:
-		*v = 0
-	case *int8:
-		*v = 0
-	case *int16:
-		*v = 0
-	case *int32:
-		*v = 0
-	case *int64:
-		*v = 0
-	case *uint:
-		*v = 0
-	case *uint8:
-		*v = 0
-	case *uint16:
-		*v = 0
-	case *uint32:
-		*v = 0
-	case *uint64:
-		*v = 0
-	case *float32:
-		*v = 0
-	case *float64:
-		*v = 0
-	case *[]uint8:
-		*v = nil
-	case *Raw:
-		*v = nil
-	case *time.Time:
-		*v = time.Time{}
-	case reflect.Value:
-		if v, canDecode = isDecodeable(v); canDecode && v.CanSet() {
-			v.Set(reflect.Zero(v.Type()))
-		} // TODO: else drain if chan, clear if map, set all to nil if slice???
-	default:
-		if !fastpathDecodeSetZeroTypeSwitch(iv) {
-			v := reflect.ValueOf(iv)
-			if v, canDecode = isDecodeable(v); canDecode && v.CanSet() {
-				v.Set(reflect.Zero(v.Type()))
-			} // TODO: else drain if chan, clear if map, set all to nil if slice???
-		}
-	}
-}
-
-func (d *Decoder) decode(iv interface{}) {
-	// a switch with only concrete types can be optimized.
-	// consequently, we deal with nil and interfaces outside the switch.
-
-	if iv == nil {
-		d.errorstr(errstrCannotDecodeIntoNil)
-		return
-	}
-
-	switch v := iv.(type) {
-	// case nil:
-	// case Selfer:
-	case reflect.Value:
-		v = d.ensureDecodeable(v)
-		d.decodeValue(v, nil, true)
-
-	case *string:
-		*v = d.d.DecodeString()
-	case *bool:
-		*v = d.d.DecodeBool()
-	case *int:
-		*v = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
-	case *int8:
-		*v = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
-	case *int16:
-		*v = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
-	case *int32:
-		*v = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
-	case *int64:
-		*v = d.d.DecodeInt64()
-	case *uint:
-		*v = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
-	case *uint8:
-		*v = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
-	case *uint16:
-		*v = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
-	case *uint32:
-		*v = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
-	case *uint64:
-		*v = d.d.DecodeUint64()
-	case *float32:
-		f64 := d.d.DecodeFloat64()
-		if chkOvf.Float32(f64) {
-			d.errorf("float32 overflow: %v", f64)
-		}
-		*v = float32(f64)
-	case *float64:
-		*v = d.d.DecodeFloat64()
-	case *[]uint8:
-		*v = d.d.DecodeBytes(*v, false)
-	case []uint8:
-		b := d.d.DecodeBytes(v, false)
-		if !(len(b) > 0 && len(b) == len(v) && &b[0] == &v[0]) {
-			copy(v, b)
-		}
-	case *time.Time:
-		*v = d.d.DecodeTime()
-	case *Raw:
-		*v = d.rawBytes()
-
-	case *interface{}:
-		d.decodeValue(reflect.ValueOf(iv).Elem(), nil, true)
-		// d.decodeValueNotNil(reflect.ValueOf(iv).Elem())
-
-	default:
-		if v, ok := iv.(Selfer); ok {
-			v.CodecDecodeSelf(d)
-		} else if !fastpathDecodeTypeSwitch(iv, d) {
-			v := reflect.ValueOf(iv)
-			v = d.ensureDecodeable(v)
-			d.decodeValue(v, nil, false)
-			// d.decodeValueFallback(v)
-		}
-	}
-}
-
-func (d *Decoder) decodeValue(rv reflect.Value, fn *codecFn, chkAll bool) {
-	// If stream is not containing a nil value, then we can deref to the base
-	// non-pointer value, and decode into that.
-	var rvp reflect.Value
-	var rvpValid bool
-	if rv.Kind() == reflect.Ptr {
-		rvpValid = true
-		for {
-			if rv.IsNil() {
-				rv.Set(reflect.New(rv.Type().Elem()))
-			}
-			rvp = rv
-			rv = rv.Elem()
-			if rv.Kind() != reflect.Ptr {
-				break
-			}
-		}
-	}
-
-	if fn == nil {
-		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
-		fn = d.h.fn(rv.Type(), chkAll, true) // chkAll, chkAll)
-	}
-	if fn.i.addrD {
-		if rvpValid {
-			fn.fd(d, &fn.i, rvp)
-		} else if rv.CanAddr() {
-			fn.fd(d, &fn.i, rv.Addr())
-		} else if !fn.i.addrF {
-			fn.fd(d, &fn.i, rv)
-		} else {
-			d.errorf("cannot decode into a non-pointer value")
-		}
-	} else {
-		fn.fd(d, &fn.i, rv)
-	}
-	// return rv
-}
-
-func (d *Decoder) structFieldNotFound(index int, rvkencname string) {
-	// NOTE: rvkencname may be a stringView, so don't pass it to another function.
-	if d.h.ErrorIfNoField {
-		if index >= 0 {
-			d.errorf("no matching struct field found when decoding stream array at index %v", index)
-			return
-		} else if rvkencname != "" {
-			d.errorf("no matching struct field found when decoding stream map with key " + rvkencname)
-			return
-		}
-	}
-	d.swallow()
-}
-
-func (d *Decoder) arrayCannotExpand(sliceLen, streamLen int) {
-	if d.h.ErrorIfNoArrayExpand {
-		d.errorf("cannot expand array len during decode from %v to %v", sliceLen, streamLen)
-	}
-}
-
-func isDecodeable(rv reflect.Value) (rv2 reflect.Value, canDecode bool) {
-	switch rv.Kind() {
-	case reflect.Array:
-		return rv, rv.CanAddr()
-	case reflect.Ptr:
-		if !rv.IsNil() {
-			return rv.Elem(), true
-		}
-	case reflect.Slice, reflect.Chan, reflect.Map:
-		if !rv.IsNil() {
-			return rv, true
-		}
-	}
-	return
-}
-
-func (d *Decoder) ensureDecodeable(rv reflect.Value) (rv2 reflect.Value) {
-	// decode can take any reflect.Value that is a inherently addressable i.e.
-	//   - array
-	//   - non-nil chan    (we will SEND to it)
-	//   - non-nil slice   (we will set its elements)
-	//   - non-nil map     (we will put into it)
-	//   - non-nil pointer (we can "update" it)
-	rv2, canDecode := isDecodeable(rv)
-	if canDecode {
-		return
-	}
-	if !rv.IsValid() {
-		d.errorstr(errstrCannotDecodeIntoNil)
-		return
-	}
-	if !rv.CanInterface() {
-		d.errorf("cannot decode into a value without an interface: %v", rv)
-		return
-	}
-	rvi := rv2i(rv)
-	rvk := rv.Kind()
-	d.errorf("cannot decode into value of kind: %v, type: %T, %v", rvk, rvi, rvi)
-	return
-}
-
-func (d *Decoder) depthIncr() {
-	d.depth++
-	if d.depth >= d.maxdepth {
-		panic(errMaxDepthExceeded)
-	}
-}
-
-func (d *Decoder) depthDecr() {
-	d.depth--
-}
-
-// Possibly get an interned version of a string
-//
-// This should mostly be used for map keys, where the key type is string.
-// This is because keys of a map/struct are typically reused across many objects.
-func (d *Decoder) string(v []byte) (s string) {
-	if d.is == nil {
-		return string(v) // don't return stringView, as we need a real string here.
-	}
-	s, ok := d.is[string(v)] // no allocation here, per go implementation
-	if !ok {
-		s = string(v) // new allocation here
-		d.is[s] = s
-	}
-	return s
-}
-
-// nextValueBytes returns the next value in the stream as a set of bytes.
-func (d *Decoder) nextValueBytes() (bs []byte) {
-	d.d.uncacheRead()
-	d.r.track()
-	d.swallow()
-	bs = d.r.stopTrack()
-	return
-}
-
-func (d *Decoder) rawBytes() []byte {
-	// ensure that this is not a view into the bytes
-	// i.e. make new copy always.
-	bs := d.nextValueBytes()
-	bs2 := make([]byte, len(bs))
-	copy(bs2, bs)
-	return bs2
-}
-
-func (d *Decoder) wrapErr(v interface{}, err *error) {
-	*err = decodeError{codecError: codecError{name: d.hh.Name(), err: v}, pos: int(d.r.numread())}
-}
-
-// NumBytesRead returns the number of bytes read
-func (d *Decoder) NumBytesRead() int {
-	return int(d.r.numread())
-}
-
-// --------------------------------------------------
-
-// decSliceHelper assists when decoding into a slice, from a map or an array in the stream.
-// A slice can be set from a map or array in stream. This supports the MapBySlice interface.
-type decSliceHelper struct {
-	d *Decoder
-	// ct valueType
-	array bool
-}
-
-func (d *Decoder) decSliceHelperStart() (x decSliceHelper, clen int) {
-	dd := d.d
-	ctyp := dd.ContainerType()
-	switch ctyp {
-	case valueTypeArray:
-		x.array = true
-		clen = dd.ReadArrayStart()
-	case valueTypeMap:
-		clen = dd.ReadMapStart() * 2
-	default:
-		d.errorf("only encoded map or array can be decoded into a slice (%d)", ctyp)
-	}
-	// x.ct = ctyp
-	x.d = d
-	return
-}
-
-func (x decSliceHelper) End() {
-	if x.array {
-		x.d.d.ReadArrayEnd()
-	} else {
-		x.d.d.ReadMapEnd()
-	}
-}
-
-func (x decSliceHelper) ElemContainerState(index int) {
-	if x.array {
-		x.d.d.ReadArrayElem()
-	} else if index%2 == 0 {
-		x.d.d.ReadMapElemKey()
-	} else {
-		x.d.d.ReadMapElemValue()
-	}
-}
-
-func decByteSlice(r *decReaderSwitch, clen, maxInitLen int, bs []byte) (bsOut []byte) {
-	if clen == 0 {
-		return zeroByteSlice
-	}
-	if len(bs) == clen {
-		bsOut = bs
-		r.readb(bsOut)
-	} else if cap(bs) >= clen {
-		bsOut = bs[:clen]
-		r.readb(bsOut)
-	} else {
-		// bsOut = make([]byte, clen)
-		len2 := decInferLen(clen, maxInitLen, 1)
-		bsOut = make([]byte, len2)
-		r.readb(bsOut)
-		for len2 < clen {
-			len3 := decInferLen(clen-len2, maxInitLen, 1)
-			bs3 := bsOut
-			bsOut = make([]byte, len2+len3)
-			copy(bsOut, bs3)
-			r.readb(bsOut[len2:])
-			len2 += len3
-		}
-	}
-	return
-}
-
-// func decByteSliceZeroCopy(r decReader, clen, maxInitLen int, bs []byte) (bsOut []byte) {
-// 	if _, ok := r.(*bytesDecReader); ok && clen <= maxInitLen {
-// 		return r.readx(clen)
-// 	}
-// 	return decByteSlice(r, clen, maxInitLen, bs)
-// }
-
-func detachZeroCopyBytes(isBytesReader bool, dest []byte, in []byte) (out []byte) {
-	if xlen := len(in); xlen > 0 {
-		if isBytesReader || xlen <= scratchByteArrayLen {
-			if cap(dest) >= xlen {
-				out = dest[:xlen]
-			} else {
-				out = make([]byte, xlen)
-			}
-			copy(out, in)
-			return
-		}
-	}
-	return in
-}
-
-// decInferLen will infer a sensible length, given the following:
-//    - clen: length wanted.
-//    - maxlen: max length to be returned.
-//      if <= 0, it is unset, and we infer it based on the unit size
-//    - unit: number of bytes for each element of the collection
-func decInferLen(clen, maxlen, unit int) (rvlen int) {
-	// handle when maxlen is not set i.e. <= 0
-	if clen <= 0 {
-		return
-	}
-	if unit == 0 {
-		return clen
-	}
-	if maxlen <= 0 {
-		// no maxlen defined. Use maximum of 256K memory, with a floor of 4K items.
-		// maxlen = 256 * 1024 / unit
-		// if maxlen < (4 * 1024) {
-		// 	maxlen = 4 * 1024
-		// }
-		if unit < (256 / 4) {
-			maxlen = 256 * 1024 / unit
-		} else {
-			maxlen = 4 * 1024
-		}
-	}
-	if clen > maxlen {
-		rvlen = maxlen
-	} else {
-		rvlen = clen
-	}
-	return
-}
-
-func expandSliceRV(s reflect.Value, st reflect.Type, canChange bool, stElemSize, num, slen, scap int) (
-	s2 reflect.Value, scap2 int, changed bool, err string) {
-	l1 := slen + num // new slice length
-	if l1 < slen {
-		err = errmsgExpandSliceOverflow
-		return
-	}
-	if l1 <= scap {
-		if s.CanSet() {
-			s.SetLen(l1)
-		} else if canChange {
-			s2 = s.Slice(0, l1)
-			scap2 = scap
-			changed = true
-		} else {
-			err = errmsgExpandSliceCannotChange
-			return
-		}
-		return
-	}
-	if !canChange {
-		err = errmsgExpandSliceCannotChange
-		return
-	}
-	scap2 = growCap(scap, stElemSize, num)
-	s2 = reflect.MakeSlice(st, l1, scap2)
-	changed = true
-	reflect.Copy(s2, s)
-	return
-}
-
-func decReadFull(r io.Reader, bs []byte) (n uint, err error) {
-	var nn int
-	for n < uint(len(bs)) && err == nil {
-		nn, err = r.Read(bs[n:])
-		if nn > 0 {
-			if err == io.EOF {
-				// leave EOF for next time
-				err = nil
-			}
-			n += uint(nn)
-		}
-	}
-	// xdebugf("decReadFull: len(bs): %v, n: %v, err: %v", len(bs), n, err)
-	// do not do this - it serves no purpose
-	// if n != len(bs) && err == io.EOF { err = io.ErrUnexpectedEOF }
-	return
-}

+ 0 - 1761
vendor/github.com/ugorji/go/codec/encode.go

@@ -1,1761 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"encoding"
-	"errors"
-	"fmt"
-	"io"
-	"reflect"
-	"runtime"
-	"sort"
-	"strconv"
-	"time"
-)
-
-// defEncByteBufSize is the default size of []byte used
-// for bufio buffer or []byte (when nil passed)
-const defEncByteBufSize = 1 << 10 // 4:16, 6:64, 8:256, 10:1024
-
-var errEncoderNotInitialized = errors.New("Encoder not initialized")
-
-/*
-
-// encWriter abstracts writing to a byte array or to an io.Writer.
-//
-//
-// Deprecated: Use encWriterSwitch instead.
-type encWriter interface {
-	writeb([]byte)
-	writestr(string)
-	writen1(byte)
-	writen2(byte, byte)
-	end()
-}
-
-*/
-
-// encDriver abstracts the actual codec (binc vs msgpack, etc)
-type encDriver interface {
-	EncodeNil()
-	EncodeInt(i int64)
-	EncodeUint(i uint64)
-	EncodeBool(b bool)
-	EncodeFloat32(f float32)
-	EncodeFloat64(f float64)
-	// encodeExtPreamble(xtag byte, length int)
-	EncodeRawExt(re *RawExt, e *Encoder)
-	EncodeExt(v interface{}, xtag uint64, ext Ext, e *Encoder)
-	// Deprecated: try to use EncodeStringEnc instead
-	EncodeString(c charEncoding, v string)
-	// c cannot be cRAW
-	EncodeStringEnc(c charEncoding, v string)
-	// EncodeSymbol(v string)
-	// Deprecated: try to use EncodeStringBytesRaw instead
-	EncodeStringBytes(c charEncoding, v []byte)
-	EncodeStringBytesRaw(v []byte)
-	EncodeTime(time.Time)
-	//encBignum(f *big.Int)
-	//encStringRunes(c charEncoding, v []rune)
-	WriteArrayStart(length int)
-	WriteArrayElem()
-	WriteArrayEnd()
-	WriteMapStart(length int)
-	WriteMapElemKey()
-	WriteMapElemValue()
-	WriteMapEnd()
-
-	reset()
-	atEndOfEncode()
-}
-
-type encDriverAsis interface {
-	EncodeAsis(v []byte)
-}
-
-type encodeError struct {
-	codecError
-}
-
-func (e encodeError) Error() string {
-	return fmt.Sprintf("%s encode error: %v", e.name, e.err)
-}
-
-type encDriverNoopContainerWriter struct{}
-
-func (encDriverNoopContainerWriter) WriteArrayStart(length int) {}
-func (encDriverNoopContainerWriter) WriteArrayElem()            {}
-func (encDriverNoopContainerWriter) WriteArrayEnd()             {}
-func (encDriverNoopContainerWriter) WriteMapStart(length int)   {}
-func (encDriverNoopContainerWriter) WriteMapElemKey()           {}
-func (encDriverNoopContainerWriter) WriteMapElemValue()         {}
-func (encDriverNoopContainerWriter) WriteMapEnd()               {}
-func (encDriverNoopContainerWriter) atEndOfEncode()             {}
-
-type encDriverTrackContainerWriter struct {
-	c containerState
-}
-
-func (e *encDriverTrackContainerWriter) WriteArrayStart(length int) { e.c = containerArrayStart }
-func (e *encDriverTrackContainerWriter) WriteArrayElem()            { e.c = containerArrayElem }
-func (e *encDriverTrackContainerWriter) WriteArrayEnd()             { e.c = containerArrayEnd }
-func (e *encDriverTrackContainerWriter) WriteMapStart(length int)   { e.c = containerMapStart }
-func (e *encDriverTrackContainerWriter) WriteMapElemKey()           { e.c = containerMapKey }
-func (e *encDriverTrackContainerWriter) WriteMapElemValue()         { e.c = containerMapValue }
-func (e *encDriverTrackContainerWriter) WriteMapEnd()               { e.c = containerMapEnd }
-func (e *encDriverTrackContainerWriter) atEndOfEncode()             {}
-
-// type ioEncWriterWriter interface {
-// 	WriteByte(c byte) error
-// 	WriteString(s string) (n int, err error)
-// 	Write(p []byte) (n int, err error)
-// }
-
-// EncodeOptions captures configuration options during encode.
-type EncodeOptions struct {
-	// WriterBufferSize is the size of the buffer used when writing.
-	//
-	// if > 0, we use a smart buffer internally for performance purposes.
-	WriterBufferSize int
-
-	// ChanRecvTimeout is the timeout used when selecting from a chan.
-	//
-	// Configuring this controls how we receive from a chan during the encoding process.
-	//   - If ==0, we only consume the elements currently available in the chan.
-	//   - if  <0, we consume until the chan is closed.
-	//   - If  >0, we consume until this timeout.
-	ChanRecvTimeout time.Duration
-
-	// StructToArray specifies to encode a struct as an array, and not as a map
-	StructToArray bool
-
-	// Canonical representation means that encoding a value will always result in the same
-	// sequence of bytes.
-	//
-	// This only affects maps, as the iteration order for maps is random.
-	//
-	// The implementation MAY use the natural sort order for the map keys if possible:
-	//
-	//     - If there is a natural sort order (ie for number, bool, string or []byte keys),
-	//       then the map keys are first sorted in natural order and then written
-	//       with corresponding map values to the strema.
-	//     - If there is no natural sort order, then the map keys will first be
-	//       encoded into []byte, and then sorted,
-	//       before writing the sorted keys and the corresponding map values to the stream.
-	//
-	Canonical bool
-
-	// CheckCircularRef controls whether we check for circular references
-	// and error fast during an encode.
-	//
-	// If enabled, an error is received if a pointer to a struct
-	// references itself either directly or through one of its fields (iteratively).
-	//
-	// This is opt-in, as there may be a performance hit to checking circular references.
-	CheckCircularRef bool
-
-	// RecursiveEmptyCheck controls whether we descend into interfaces, structs and pointers
-	// when checking if a value is empty.
-	//
-	// Note that this may make OmitEmpty more expensive, as it incurs a lot more reflect calls.
-	RecursiveEmptyCheck bool
-
-	// Raw controls whether we encode Raw values.
-	// This is a "dangerous" option and must be explicitly set.
-	// If set, we blindly encode Raw values as-is, without checking
-	// if they are a correct representation of a value in that format.
-	// If unset, we error out.
-	Raw bool
-
-	// // AsSymbols defines what should be encoded as symbols.
-	// //
-	// // Encoding as symbols can reduce the encoded size significantly.
-	// //
-	// // However, during decoding, each string to be encoded as a symbol must
-	// // be checked to see if it has been seen before. Consequently, encoding time
-	// // will increase if using symbols, because string comparisons has a clear cost.
-	// //
-	// // Sample values:
-	// //   AsSymbolNone
-	// //   AsSymbolAll
-	// //   AsSymbolMapStringKeys
-	// //   AsSymbolMapStringKeysFlag | AsSymbolStructFieldNameFlag
-	// AsSymbols AsSymbolFlag
-}
-
-// ---------------------------------------------
-
-/*
-
-type ioEncStringWriter interface {
-	WriteString(s string) (n int, err error)
-}
-
-// ioEncWriter implements encWriter and can write to an io.Writer implementation
-type ioEncWriter struct {
-	w  io.Writer
-	ww io.Writer
-	bw io.ByteWriter
-	sw ioEncStringWriter
-	fw ioFlusher
-	b  [8]byte
-}
-
-func (z *ioEncWriter) reset(w io.Writer) {
-	z.w = w
-	var ok bool
-	if z.bw, ok = w.(io.ByteWriter); !ok {
-		z.bw = z
-	}
-	if z.sw, ok = w.(ioEncStringWriter); !ok {
-		z.sw = z
-	}
-	z.fw, _ = w.(ioFlusher)
-	z.ww = w
-}
-
-func (z *ioEncWriter) WriteByte(b byte) (err error) {
-	z.b[0] = b
-	_, err = z.w.Write(z.b[:1])
-	return
-}
-
-func (z *ioEncWriter) WriteString(s string) (n int, err error) {
-	return z.w.Write(bytesView(s))
-}
-
-func (z *ioEncWriter) writeb(bs []byte) {
-	if _, err := z.ww.Write(bs); err != nil {
-		panic(err)
-	}
-}
-
-func (z *ioEncWriter) writestr(s string) {
-	if _, err := z.sw.WriteString(s); err != nil {
-		panic(err)
-	}
-}
-
-func (z *ioEncWriter) writen1(b byte) {
-	if err := z.bw.WriteByte(b); err != nil {
-		panic(err)
-	}
-}
-
-func (z *ioEncWriter) writen2(b1, b2 byte) {
-	var err error
-	if err = z.bw.WriteByte(b1); err == nil {
-		if err = z.bw.WriteByte(b2); err == nil {
-			return
-		}
-	}
-	panic(err)
-}
-
-// func (z *ioEncWriter) writen5(b1, b2, b3, b4, b5 byte) {
-// 	z.b[0], z.b[1], z.b[2], z.b[3], z.b[4] = b1, b2, b3, b4, b5
-// 	if _, err := z.ww.Write(z.b[:5]); err != nil {
-// 		panic(err)
-// 	}
-// }
-
-//go:noinline - so *encWriterSwitch.XXX has the bytesEncAppender.XXX inlined
-func (z *ioEncWriter) end() {
-	if z.fw != nil {
-		if err := z.fw.Flush(); err != nil {
-			panic(err)
-		}
-	}
-}
-
-*/
-
-// ---------------------------------------------
-
-// bufioEncWriter
-type bufioEncWriter struct {
-	buf []byte
-	w   io.Writer
-	n   int
-	sz  int // buf size
-
-	// Extensions can call Encode() within a current Encode() call.
-	// We need to know when the top level Encode() call returns,
-	// so we can decide whether to Release() or not.
-	calls uint16 // what depth in mustDecode are we in now.
-
-	_ [6]uint8 // padding
-
-	bytesBufPooler
-
-	_ [1]uint64 // padding
-	// a int
-	// b   [4]byte
-	// err
-}
-
-func (z *bufioEncWriter) reset(w io.Writer, bufsize int) {
-	z.w = w
-	z.n = 0
-	z.calls = 0
-	if bufsize <= 0 {
-		bufsize = defEncByteBufSize
-	}
-	z.sz = bufsize
-	if cap(z.buf) >= bufsize {
-		z.buf = z.buf[:cap(z.buf)]
-	} else {
-		z.buf = z.bytesBufPooler.get(bufsize)
-		// z.buf = make([]byte, bufsize)
-	}
-}
-
-func (z *bufioEncWriter) release() {
-	z.buf = nil
-	z.bytesBufPooler.end()
-}
-
-//go:noinline - flush only called intermittently
-func (z *bufioEncWriter) flush() {
-	n, err := z.w.Write(z.buf[:z.n])
-	z.n -= n
-	if z.n > 0 && err == nil {
-		err = io.ErrShortWrite
-	}
-	if err != nil {
-		if n > 0 && z.n > 0 {
-			copy(z.buf, z.buf[n:z.n+n])
-		}
-		panic(err)
-	}
-}
-
-func (z *bufioEncWriter) writeb(s []byte) {
-LOOP:
-	a := len(z.buf) - z.n
-	if len(s) > a {
-		z.n += copy(z.buf[z.n:], s[:a])
-		s = s[a:]
-		z.flush()
-		goto LOOP
-	}
-	z.n += copy(z.buf[z.n:], s)
-}
-
-func (z *bufioEncWriter) writestr(s string) {
-	// z.writeb(bytesView(s)) // inlined below
-LOOP:
-	a := len(z.buf) - z.n
-	if len(s) > a {
-		z.n += copy(z.buf[z.n:], s[:a])
-		s = s[a:]
-		z.flush()
-		goto LOOP
-	}
-	z.n += copy(z.buf[z.n:], s)
-}
-
-func (z *bufioEncWriter) writen1(b1 byte) {
-	if 1 > len(z.buf)-z.n {
-		z.flush()
-	}
-	z.buf[z.n] = b1
-	z.n++
-}
-
-func (z *bufioEncWriter) writen2(b1, b2 byte) {
-	if 2 > len(z.buf)-z.n {
-		z.flush()
-	}
-	z.buf[z.n+1] = b2
-	z.buf[z.n] = b1
-	z.n += 2
-}
-
-func (z *bufioEncWriter) end() {
-	if z.n > 0 {
-		z.flush()
-	}
-}
-
-// ---------------------------------------------
-
-// bytesEncAppender implements encWriter and can write to an byte slice.
-type bytesEncAppender struct {
-	b   []byte
-	out *[]byte
-}
-
-func (z *bytesEncAppender) writeb(s []byte) {
-	z.b = append(z.b, s...)
-}
-func (z *bytesEncAppender) writestr(s string) {
-	z.b = append(z.b, s...)
-}
-func (z *bytesEncAppender) writen1(b1 byte) {
-	z.b = append(z.b, b1)
-}
-func (z *bytesEncAppender) writen2(b1, b2 byte) {
-	z.b = append(z.b, b1, b2)
-}
-func (z *bytesEncAppender) end() {
-	*(z.out) = z.b
-}
-func (z *bytesEncAppender) reset(in []byte, out *[]byte) {
-	z.b = in[:0]
-	z.out = out
-}
-
-// ---------------------------------------------
-
-func (e *Encoder) rawExt(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeRawExt(rv2i(rv).(*RawExt), e)
-}
-
-func (e *Encoder) ext(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeExt(rv2i(rv), f.xfTag, f.xfFn, e)
-}
-
-func (e *Encoder) selferMarshal(f *codecFnInfo, rv reflect.Value) {
-	rv2i(rv).(Selfer).CodecEncodeSelf(e)
-}
-
-func (e *Encoder) binaryMarshal(f *codecFnInfo, rv reflect.Value) {
-	bs, fnerr := rv2i(rv).(encoding.BinaryMarshaler).MarshalBinary()
-	e.marshalRaw(bs, fnerr)
-}
-
-func (e *Encoder) textMarshal(f *codecFnInfo, rv reflect.Value) {
-	bs, fnerr := rv2i(rv).(encoding.TextMarshaler).MarshalText()
-	e.marshalUtf8(bs, fnerr)
-}
-
-func (e *Encoder) jsonMarshal(f *codecFnInfo, rv reflect.Value) {
-	bs, fnerr := rv2i(rv).(jsonMarshaler).MarshalJSON()
-	e.marshalAsis(bs, fnerr)
-}
-
-func (e *Encoder) raw(f *codecFnInfo, rv reflect.Value) {
-	e.rawBytes(rv2i(rv).(Raw))
-}
-
-func (e *Encoder) kInvalid(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeNil()
-}
-
-func (e *Encoder) kErr(f *codecFnInfo, rv reflect.Value) {
-	e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv)
-}
-
-func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
-	ti := f.ti
-	ee := e.e
-	// array may be non-addressable, so we have to manage with care
-	//   (don't call rv.Bytes, rv.Slice, etc).
-	// E.g. type struct S{B [2]byte};
-	//   Encode(S{}) will bomb on "panic: slice of unaddressable array".
-	if f.seq != seqTypeArray {
-		if rv.IsNil() {
-			ee.EncodeNil()
-			return
-		}
-		// If in this method, then there was no extension function defined.
-		// So it's okay to treat as []byte.
-		if ti.rtid == uint8SliceTypId {
-			ee.EncodeStringBytesRaw(rv.Bytes())
-			return
-		}
-	}
-	if f.seq == seqTypeChan && ti.chandir&uint8(reflect.RecvDir) == 0 {
-		e.errorf("send-only channel cannot be encoded")
-	}
-	elemsep := e.esep
-	rtelem := ti.elem
-	rtelemIsByte := uint8TypId == rt2id(rtelem) // NOT rtelem.Kind() == reflect.Uint8
-	var l int
-	// if a slice, array or chan of bytes, treat specially
-	if rtelemIsByte {
-		switch f.seq {
-		case seqTypeSlice:
-			ee.EncodeStringBytesRaw(rv.Bytes())
-		case seqTypeArray:
-			l = rv.Len()
-			if rv.CanAddr() {
-				ee.EncodeStringBytesRaw(rv.Slice(0, l).Bytes())
-			} else {
-				var bs []byte
-				if l <= cap(e.b) {
-					bs = e.b[:l]
-				} else {
-					bs = make([]byte, l)
-				}
-				reflect.Copy(reflect.ValueOf(bs), rv)
-				ee.EncodeStringBytesRaw(bs)
-			}
-		case seqTypeChan:
-			// do not use range, so that the number of elements encoded
-			// does not change, and encoding does not hang waiting on someone to close chan.
-			// for b := range rv2i(rv).(<-chan byte) { bs = append(bs, b) }
-			// ch := rv2i(rv).(<-chan byte) // fix error - that this is a chan byte, not a <-chan byte.
-
-			if rv.IsNil() {
-				ee.EncodeNil()
-				break
-			}
-			bs := e.b[:0]
-			irv := rv2i(rv)
-			ch, ok := irv.(<-chan byte)
-			if !ok {
-				ch = irv.(chan byte)
-			}
-
-		L1:
-			switch timeout := e.h.ChanRecvTimeout; {
-			case timeout == 0: // only consume available
-				for {
-					select {
-					case b := <-ch:
-						bs = append(bs, b)
-					default:
-						break L1
-					}
-				}
-			case timeout > 0: // consume until timeout
-				tt := time.NewTimer(timeout)
-				for {
-					select {
-					case b := <-ch:
-						bs = append(bs, b)
-					case <-tt.C:
-						// close(tt.C)
-						break L1
-					}
-				}
-			default: // consume until close
-				for b := range ch {
-					bs = append(bs, b)
-				}
-			}
-
-			ee.EncodeStringBytesRaw(bs)
-		}
-		return
-	}
-
-	// if chan, consume chan into a slice, and work off that slice.
-	if f.seq == seqTypeChan {
-		rvcs := reflect.Zero(reflect.SliceOf(rtelem))
-		timeout := e.h.ChanRecvTimeout
-		if timeout < 0 { // consume until close
-			for {
-				recv, recvOk := rv.Recv()
-				if !recvOk {
-					break
-				}
-				rvcs = reflect.Append(rvcs, recv)
-			}
-		} else {
-			cases := make([]reflect.SelectCase, 2)
-			cases[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: rv}
-			if timeout == 0 {
-				cases[1] = reflect.SelectCase{Dir: reflect.SelectDefault}
-			} else {
-				tt := time.NewTimer(timeout)
-				cases[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(tt.C)}
-			}
-			for {
-				chosen, recv, recvOk := reflect.Select(cases)
-				if chosen == 1 || !recvOk {
-					break
-				}
-				rvcs = reflect.Append(rvcs, recv)
-			}
-		}
-		rv = rvcs // TODO: ensure this doesn't mess up anywhere that rv of kind chan is expected
-	}
-
-	l = rv.Len()
-	if ti.mbs {
-		if l%2 == 1 {
-			e.errorf("mapBySlice requires even slice length, but got %v", l)
-			return
-		}
-		ee.WriteMapStart(l / 2)
-	} else {
-		ee.WriteArrayStart(l)
-	}
-
-	if l > 0 {
-		var fn *codecFn
-		for rtelem.Kind() == reflect.Ptr {
-			rtelem = rtelem.Elem()
-		}
-		// if kind is reflect.Interface, do not pre-determine the
-		// encoding type, because preEncodeValue may break it down to
-		// a concrete type and kInterface will bomb.
-		if rtelem.Kind() != reflect.Interface {
-			fn = e.h.fn(rtelem, true, true)
-		}
-		for j := 0; j < l; j++ {
-			if elemsep {
-				if ti.mbs {
-					if j%2 == 0 {
-						ee.WriteMapElemKey()
-					} else {
-						ee.WriteMapElemValue()
-					}
-				} else {
-					ee.WriteArrayElem()
-				}
-			}
-			e.encodeValue(rv.Index(j), fn, true)
-		}
-	}
-
-	if ti.mbs {
-		ee.WriteMapEnd()
-	} else {
-		ee.WriteArrayEnd()
-	}
-}
-
-func (e *Encoder) kStructNoOmitempty(f *codecFnInfo, rv reflect.Value) {
-	fti := f.ti
-	tisfi := fti.sfiSrc
-	toMap := !(fti.toArray || e.h.StructToArray)
-	if toMap {
-		tisfi = fti.sfiSort
-	}
-
-	ee := e.e
-
-	sfn := structFieldNode{v: rv, update: false}
-	if toMap {
-		ee.WriteMapStart(len(tisfi))
-		if e.esep {
-			for _, si := range tisfi {
-				ee.WriteMapElemKey()
-				// ee.EncodeStringEnc(cUTF8, si.encName)
-				e.kStructFieldKey(fti.keyType, si)
-				ee.WriteMapElemValue()
-				e.encodeValue(sfn.field(si), nil, true)
-			}
-		} else {
-			for _, si := range tisfi {
-				// ee.EncodeStringEnc(cUTF8, si.encName)
-				e.kStructFieldKey(fti.keyType, si)
-				e.encodeValue(sfn.field(si), nil, true)
-			}
-		}
-		ee.WriteMapEnd()
-	} else {
-		ee.WriteArrayStart(len(tisfi))
-		if e.esep {
-			for _, si := range tisfi {
-				ee.WriteArrayElem()
-				e.encodeValue(sfn.field(si), nil, true)
-			}
-		} else {
-			for _, si := range tisfi {
-				e.encodeValue(sfn.field(si), nil, true)
-			}
-		}
-		ee.WriteArrayEnd()
-	}
-}
-
-func (e *Encoder) kStructFieldKey(keyType valueType, s *structFieldInfo) {
-	var m must
-	// use if-else-if, not switch (which compiles to binary-search)
-	// since keyType is typically valueTypeString, branch prediction is pretty good.
-	if keyType == valueTypeString {
-		if e.js && s.encNameAsciiAlphaNum { // keyType == valueTypeString
-			e.w.writen1('"')
-			e.w.writestr(s.encName)
-			e.w.writen1('"')
-		} else { // keyType == valueTypeString
-			e.e.EncodeStringEnc(cUTF8, s.encName)
-		}
-	} else if keyType == valueTypeInt {
-		e.e.EncodeInt(m.Int(strconv.ParseInt(s.encName, 10, 64)))
-	} else if keyType == valueTypeUint {
-		e.e.EncodeUint(m.Uint(strconv.ParseUint(s.encName, 10, 64)))
-	} else if keyType == valueTypeFloat {
-		e.e.EncodeFloat64(m.Float(strconv.ParseFloat(s.encName, 64)))
-	}
-}
-
-func (e *Encoder) kStructFieldKeyName(keyType valueType, encName string) {
-	var m must
-	// use if-else-if, not switch (which compiles to binary-search)
-	// since keyType is typically valueTypeString, branch prediction is pretty good.
-	if keyType == valueTypeString {
-		e.e.EncodeStringEnc(cUTF8, encName)
-	} else if keyType == valueTypeInt {
-		e.e.EncodeInt(m.Int(strconv.ParseInt(encName, 10, 64)))
-	} else if keyType == valueTypeUint {
-		e.e.EncodeUint(m.Uint(strconv.ParseUint(encName, 10, 64)))
-	} else if keyType == valueTypeFloat {
-		e.e.EncodeFloat64(m.Float(strconv.ParseFloat(encName, 64)))
-	}
-}
-
-func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
-	fti := f.ti
-	elemsep := e.esep
-	tisfi := fti.sfiSrc
-	var newlen int
-	toMap := !(fti.toArray || e.h.StructToArray)
-	var mf map[string]interface{}
-	if f.ti.mf {
-		mf = rv2i(rv).(MissingFielder).CodecMissingFields()
-		toMap = true
-		newlen += len(mf)
-	} else if f.ti.mfp {
-		if rv.CanAddr() {
-			mf = rv2i(rv.Addr()).(MissingFielder).CodecMissingFields()
-		} else {
-			// make a new addressable value of same one, and use it
-			rv2 := reflect.New(rv.Type())
-			rv2.Elem().Set(rv)
-			mf = rv2i(rv2).(MissingFielder).CodecMissingFields()
-		}
-		toMap = true
-		newlen += len(mf)
-	}
-	// if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct)
-	if toMap {
-		tisfi = fti.sfiSort
-	}
-	newlen += len(tisfi)
-	ee := e.e
-
-	// Use sync.Pool to reduce allocating slices unnecessarily.
-	// The cost of sync.Pool is less than the cost of new allocation.
-	//
-	// Each element of the array pools one of encStructPool(8|16|32|64).
-	// It allows the re-use of slices up to 64 in length.
-	// A performance cost of encoding structs was collecting
-	// which values were empty and should be omitted.
-	// We needed slices of reflect.Value and string to collect them.
-	// This shared pool reduces the amount of unnecessary creation we do.
-	// The cost is that of locking sometimes, but sync.Pool is efficient
-	// enough to reduce thread contention.
-
-	// fmt.Printf(">>>>>>>>>>>>>> encode.kStruct: newlen: %d\n", newlen)
-	var spool sfiRvPooler
-	var fkvs = spool.get(newlen)
-
-	var kv sfiRv
-	recur := e.h.RecursiveEmptyCheck
-	sfn := structFieldNode{v: rv, update: false}
-	newlen = 0
-	for _, si := range tisfi {
-		// kv.r = si.field(rv, false)
-		kv.r = sfn.field(si)
-		if toMap {
-			if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
-				continue
-			}
-			kv.v = si // si.encName
-		} else {
-			// use the zero value.
-			// if a reference or struct, set to nil (so you do not output too much)
-			if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
-				switch kv.r.Kind() {
-				case reflect.Struct, reflect.Interface, reflect.Ptr,
-					reflect.Array, reflect.Map, reflect.Slice:
-					kv.r = reflect.Value{} //encode as nil
-				}
-			}
-		}
-		fkvs[newlen] = kv
-		newlen++
-	}
-	fkvs = fkvs[:newlen]
-
-	var mflen int
-	for k, v := range mf {
-		if k == "" {
-			delete(mf, k)
-			continue
-		}
-		if fti.infoFieldOmitempty && isEmptyValue(reflect.ValueOf(v), e.h.TypeInfos, recur, recur) {
-			delete(mf, k)
-			continue
-		}
-		mflen++
-	}
-
-	var j int
-	if toMap {
-		ee.WriteMapStart(newlen + mflen)
-		if elemsep {
-			for j = 0; j < len(fkvs); j++ {
-				kv = fkvs[j]
-				ee.WriteMapElemKey()
-				// ee.EncodeStringEnc(cUTF8, kv.v)
-				e.kStructFieldKey(fti.keyType, kv.v)
-				ee.WriteMapElemValue()
-				e.encodeValue(kv.r, nil, true)
-			}
-		} else {
-			for j = 0; j < len(fkvs); j++ {
-				kv = fkvs[j]
-				// ee.EncodeStringEnc(cUTF8, kv.v)
-				e.kStructFieldKey(fti.keyType, kv.v)
-				e.encodeValue(kv.r, nil, true)
-			}
-		}
-		// now, add the others
-		for k, v := range mf {
-			ee.WriteMapElemKey()
-			e.kStructFieldKeyName(fti.keyType, k)
-			ee.WriteMapElemValue()
-			e.encode(v)
-		}
-		ee.WriteMapEnd()
-	} else {
-		ee.WriteArrayStart(newlen)
-		if elemsep {
-			for j = 0; j < len(fkvs); j++ {
-				ee.WriteArrayElem()
-				e.encodeValue(fkvs[j].r, nil, true)
-			}
-		} else {
-			for j = 0; j < len(fkvs); j++ {
-				e.encodeValue(fkvs[j].r, nil, true)
-			}
-		}
-		ee.WriteArrayEnd()
-	}
-
-	// do not use defer. Instead, use explicit pool return at end of function.
-	// defer has a cost we are trying to avoid.
-	// If there is a panic and these slices are not returned, it is ok.
-	spool.end()
-}
-
-func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
-	ee := e.e
-	if rv.IsNil() {
-		ee.EncodeNil()
-		return
-	}
-
-	l := rv.Len()
-	ee.WriteMapStart(l)
-	if l == 0 {
-		ee.WriteMapEnd()
-		return
-	}
-	// var asSymbols bool
-	// determine the underlying key and val encFn's for the map.
-	// This eliminates some work which is done for each loop iteration i.e.
-	// rv.Type(), ref.ValueOf(rt).Pointer(), then check map/list for fn.
-	//
-	// However, if kind is reflect.Interface, do not pre-determine the
-	// encoding type, because preEncodeValue may break it down to
-	// a concrete type and kInterface will bomb.
-	var keyFn, valFn *codecFn
-	ti := f.ti
-	rtkey0 := ti.key
-	rtkey := rtkey0
-	rtval0 := ti.elem
-	rtval := rtval0
-	// rtkeyid := rt2id(rtkey0)
-	for rtval.Kind() == reflect.Ptr {
-		rtval = rtval.Elem()
-	}
-	if rtval.Kind() != reflect.Interface {
-		valFn = e.h.fn(rtval, true, true)
-	}
-	mks := rv.MapKeys()
-
-	if e.h.Canonical {
-		e.kMapCanonical(rtkey, rv, mks, valFn)
-		ee.WriteMapEnd()
-		return
-	}
-
-	var keyTypeIsString = stringTypId == rt2id(rtkey0) // rtkeyid
-	if !keyTypeIsString {
-		for rtkey.Kind() == reflect.Ptr {
-			rtkey = rtkey.Elem()
-		}
-		if rtkey.Kind() != reflect.Interface {
-			// rtkeyid = rt2id(rtkey)
-			keyFn = e.h.fn(rtkey, true, true)
-		}
-	}
-
-	// for j, lmks := 0, len(mks); j < lmks; j++ {
-	for j := range mks {
-		if e.esep {
-			ee.WriteMapElemKey()
-		}
-		if keyTypeIsString {
-			ee.EncodeStringEnc(cUTF8, mks[j].String())
-		} else {
-			e.encodeValue(mks[j], keyFn, true)
-		}
-		if e.esep {
-			ee.WriteMapElemValue()
-		}
-		e.encodeValue(rv.MapIndex(mks[j]), valFn, true)
-
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) kMapCanonical(rtkey reflect.Type, rv reflect.Value, mks []reflect.Value, valFn *codecFn) {
-	ee := e.e
-	elemsep := e.esep
-	// we previously did out-of-band if an extension was registered.
-	// This is not necessary, as the natural kind is sufficient for ordering.
-
-	switch rtkey.Kind() {
-	case reflect.Bool:
-		mksv := make([]boolRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Bool()
-		}
-		sort.Sort(boolRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeBool(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.String:
-		mksv := make([]stringRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.String()
-		}
-		sort.Sort(stringRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeStringEnc(cUTF8, mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
-		mksv := make([]uintRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Uint()
-		}
-		sort.Sort(uintRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeUint(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
-		mksv := make([]intRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Int()
-		}
-		sort.Sort(intRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeInt(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Float32:
-		mksv := make([]floatRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Float()
-		}
-		sort.Sort(floatRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeFloat32(float32(mksv[i].v))
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Float64:
-		mksv := make([]floatRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Float()
-		}
-		sort.Sort(floatRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeFloat64(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Struct:
-		if rv.Type() == timeTyp {
-			mksv := make([]timeRv, len(mks))
-			for i, k := range mks {
-				v := &mksv[i]
-				v.r = k
-				v.v = rv2i(k).(time.Time)
-			}
-			sort.Sort(timeRvSlice(mksv))
-			for i := range mksv {
-				if elemsep {
-					ee.WriteMapElemKey()
-				}
-				ee.EncodeTime(mksv[i].v)
-				if elemsep {
-					ee.WriteMapElemValue()
-				}
-				e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-			}
-			break
-		}
-		fallthrough
-	default:
-		// out-of-band
-		// first encode each key to a []byte first, then sort them, then record
-		var mksv []byte = make([]byte, 0, len(mks)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		mksbv := make([]bytesRv, len(mks))
-		for i, k := range mks {
-			v := &mksbv[i]
-			l := len(mksv)
-			e2.MustEncode(k)
-			v.r = k
-			v.v = mksv[l:]
-		}
-		sort.Sort(bytesRvSlice(mksbv))
-		for j := range mksbv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			e.asis(mksbv[j].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksbv[j].r), valFn, true)
-		}
-	}
-}
-
-// // --------------------------------------------------
-
-type encWriterSwitch struct {
-	// wi   *ioEncWriter
-	wb bytesEncAppender
-	wf *bufioEncWriter
-	// typ  entryType
-	bytes bool    // encoding to []byte
-	esep  bool    // whether it has elem separators
-	isas  bool    // whether e.as != nil
-	js    bool    // is json encoder?
-	be    bool    // is binary encoder?
-	_     [2]byte // padding
-	// _    [2]uint64 // padding
-	// _    uint64    // padding
-}
-
-func (z *encWriterSwitch) writeb(s []byte) {
-	if z.bytes {
-		z.wb.writeb(s)
-	} else {
-		z.wf.writeb(s)
-	}
-}
-func (z *encWriterSwitch) writestr(s string) {
-	if z.bytes {
-		z.wb.writestr(s)
-	} else {
-		z.wf.writestr(s)
-	}
-}
-func (z *encWriterSwitch) writen1(b1 byte) {
-	if z.bytes {
-		z.wb.writen1(b1)
-	} else {
-		z.wf.writen1(b1)
-	}
-}
-func (z *encWriterSwitch) writen2(b1, b2 byte) {
-	if z.bytes {
-		z.wb.writen2(b1, b2)
-	} else {
-		z.wf.writen2(b1, b2)
-	}
-}
-func (z *encWriterSwitch) end() {
-	if z.bytes {
-		z.wb.end()
-	} else {
-		z.wf.end()
-	}
-}
-
-/*
-
-// ------------------------------------------
-func (z *encWriterSwitch) writeb(s []byte) {
-	switch z.typ {
-	case entryTypeBytes:
-		z.wb.writeb(s)
-	case entryTypeIo:
-		z.wi.writeb(s)
-	default:
-		z.wf.writeb(s)
-	}
-}
-func (z *encWriterSwitch) writestr(s string) {
-	switch z.typ {
-	case entryTypeBytes:
-		z.wb.writestr(s)
-	case entryTypeIo:
-		z.wi.writestr(s)
-	default:
-		z.wf.writestr(s)
-	}
-}
-func (z *encWriterSwitch) writen1(b1 byte) {
-	switch z.typ {
-	case entryTypeBytes:
-		z.wb.writen1(b1)
-	case entryTypeIo:
-		z.wi.writen1(b1)
-	default:
-		z.wf.writen1(b1)
-	}
-}
-func (z *encWriterSwitch) writen2(b1, b2 byte) {
-	switch z.typ {
-	case entryTypeBytes:
-		z.wb.writen2(b1, b2)
-	case entryTypeIo:
-		z.wi.writen2(b1, b2)
-	default:
-		z.wf.writen2(b1, b2)
-	}
-}
-func (z *encWriterSwitch) end() {
-	switch z.typ {
-	case entryTypeBytes:
-		z.wb.end()
-	case entryTypeIo:
-		z.wi.end()
-	default:
-		z.wf.end()
-	}
-}
-
-// ------------------------------------------
-func (z *encWriterSwitch) writeb(s []byte) {
-	if z.bytes {
-		z.wb.writeb(s)
-	} else {
-		z.wi.writeb(s)
-	}
-}
-func (z *encWriterSwitch) writestr(s string) {
-	if z.bytes {
-		z.wb.writestr(s)
-	} else {
-		z.wi.writestr(s)
-	}
-}
-func (z *encWriterSwitch) writen1(b1 byte) {
-	if z.bytes {
-		z.wb.writen1(b1)
-	} else {
-		z.wi.writen1(b1)
-	}
-}
-func (z *encWriterSwitch) writen2(b1, b2 byte) {
-	if z.bytes {
-		z.wb.writen2(b1, b2)
-	} else {
-		z.wi.writen2(b1, b2)
-	}
-}
-func (z *encWriterSwitch) end() {
-	if z.bytes {
-		z.wb.end()
-	} else {
-		z.wi.end()
-	}
-}
-
-*/
-
-// Encoder writes an object to an output stream in a supported format.
-//
-// Encoder is NOT safe for concurrent use i.e. a Encoder cannot be used
-// concurrently in multiple goroutines.
-//
-// However, as Encoder could be allocation heavy to initialize, a Reset method is provided
-// so its state can be reused to decode new input streams repeatedly.
-// This is the idiomatic way to use.
-type Encoder struct {
-	panicHdl
-	// hopefully, reduce derefencing cost by laying the encWriter inside the Encoder
-	e encDriver
-
-	// NOTE: Encoder shouldn't call it's write methods,
-	// as the handler MAY need to do some coordination.
-	w *encWriterSwitch
-
-	// bw *bufio.Writer
-	as encDriverAsis
-
-	err error
-
-	h  *BasicHandle
-	hh Handle
-	// ---- cpu cache line boundary? + 3
-	encWriterSwitch
-
-	ci set
-
-	b [(5 * 8)]byte // for encoding chan or (non-addressable) [N]byte
-
-	// ---- writable fields during execution --- *try* to keep in sep cache line
-
-	// ---- cpu cache line boundary?
-	// b [scratchByteArrayLen]byte
-	// _ [cacheLineSize - scratchByteArrayLen]byte // padding
-	// b [cacheLineSize - (8 * 0)]byte // used for encoding a chan or (non-addressable) array of bytes
-}
-
-// NewEncoder returns an Encoder for encoding into an io.Writer.
-//
-// For efficiency, Users are encouraged to configure WriterBufferSize on the handle
-// OR pass in a memory buffered writer (eg bufio.Writer, bytes.Buffer).
-func NewEncoder(w io.Writer, h Handle) *Encoder {
-	e := newEncoder(h)
-	e.Reset(w)
-	return e
-}
-
-// NewEncoderBytes returns an encoder for encoding directly and efficiently
-// into a byte slice, using zero-copying to temporary slices.
-//
-// It will potentially replace the output byte slice pointed to.
-// After encoding, the out parameter contains the encoded contents.
-func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
-	e := newEncoder(h)
-	e.ResetBytes(out)
-	return e
-}
-
-func newEncoder(h Handle) *Encoder {
-	e := &Encoder{h: basicHandle(h), err: errEncoderNotInitialized}
-	e.bytes = true
-	if useFinalizers {
-		runtime.SetFinalizer(e, (*Encoder).finalize)
-		// xdebugf(">>>> new(Encoder) with finalizer")
-	}
-	e.w = &e.encWriterSwitch
-	e.hh = h
-	e.esep = h.hasElemSeparators()
-
-	return e
-}
-
-func (e *Encoder) resetCommon() {
-	// e.w = &e.encWriterSwitch
-	if e.e == nil || e.hh.recreateEncDriver(e.e) {
-		e.e = e.hh.newEncDriver(e)
-		e.as, e.isas = e.e.(encDriverAsis)
-		// e.cr, _ = e.e.(containerStateRecv)
-	}
-	e.be = e.hh.isBinary()
-	_, e.js = e.hh.(*JsonHandle)
-	e.e.reset()
-	e.err = nil
-}
-
-// Reset resets the Encoder with a new output stream.
-//
-// This accommodates using the state of the Encoder,
-// where it has "cached" information about sub-engines.
-func (e *Encoder) Reset(w io.Writer) {
-	if w == nil {
-		return
-	}
-	// var ok bool
-	e.bytes = false
-	if e.wf == nil {
-		e.wf = new(bufioEncWriter)
-	}
-	// e.typ = entryTypeUnset
-	// if e.h.WriterBufferSize > 0 {
-	// 	// bw := bufio.NewWriterSize(w, e.h.WriterBufferSize)
-	// 	// e.wi.bw = bw
-	// 	// e.wi.sw = bw
-	// 	// e.wi.fw = bw
-	// 	// e.wi.ww = bw
-	// 	if e.wf == nil {
-	// 		e.wf = new(bufioEncWriter)
-	// 	}
-	// 	e.wf.reset(w, e.h.WriterBufferSize)
-	// 	e.typ = entryTypeBufio
-	// } else {
-	// 	if e.wi == nil {
-	// 		e.wi = new(ioEncWriter)
-	// 	}
-	// 	e.wi.reset(w)
-	// 	e.typ = entryTypeIo
-	// }
-	e.wf.reset(w, e.h.WriterBufferSize)
-	// e.typ = entryTypeBufio
-
-	// e.w = e.wi
-	e.resetCommon()
-}
-
-// ResetBytes resets the Encoder with a new destination output []byte.
-func (e *Encoder) ResetBytes(out *[]byte) {
-	if out == nil {
-		return
-	}
-	var in []byte = *out
-	if in == nil {
-		in = make([]byte, defEncByteBufSize)
-	}
-	e.bytes = true
-	// e.typ = entryTypeBytes
-	e.wb.reset(in, out)
-	// e.w = &e.wb
-	e.resetCommon()
-}
-
-// Encode writes an object into a stream.
-//
-// Encoding can be configured via the struct tag for the fields.
-// The key (in the struct tags) that we look at is configurable.
-//
-// By default, we look up the "codec" key in the struct field's tags,
-// and fall bak to the "json" key if "codec" is absent.
-// That key in struct field's tag value is the key name,
-// followed by an optional comma and options.
-//
-// To set an option on all fields (e.g. omitempty on all fields), you
-// can create a field called _struct, and set flags on it. The options
-// which can be set on _struct are:
-//    - omitempty: so all fields are omitted if empty
-//    - toarray: so struct is encoded as an array
-//    - int: so struct key names are encoded as signed integers (instead of strings)
-//    - uint: so struct key names are encoded as unsigned integers (instead of strings)
-//    - float: so struct key names are encoded as floats (instead of strings)
-// More details on these below.
-//
-// Struct values "usually" encode as maps. Each exported struct field is encoded unless:
-//    - the field's tag is "-", OR
-//    - the field is empty (empty or the zero value) and its tag specifies the "omitempty" option.
-//
-// When encoding as a map, the first string in the tag (before the comma)
-// is the map key string to use when encoding.
-// ...
-// This key is typically encoded as a string.
-// However, there are instances where the encoded stream has mapping keys encoded as numbers.
-// For example, some cbor streams have keys as integer codes in the stream, but they should map
-// to fields in a structured object. Consequently, a struct is the natural representation in code.
-// For these, configure the struct to encode/decode the keys as numbers (instead of string).
-// This is done with the int,uint or float option on the _struct field (see above).
-//
-// However, struct values may encode as arrays. This happens when:
-//    - StructToArray Encode option is set, OR
-//    - the tag on the _struct field sets the "toarray" option
-// Note that omitempty is ignored when encoding struct values as arrays,
-// as an entry must be encoded for each field, to maintain its position.
-//
-// Values with types that implement MapBySlice are encoded as stream maps.
-//
-// The empty values (for omitempty option) are false, 0, any nil pointer
-// or interface value, and any array, slice, map, or string of length zero.
-//
-// Anonymous fields are encoded inline except:
-//    - the struct tag specifies a replacement name (first value)
-//    - the field is of an interface type
-//
-// Examples:
-//
-//      // NOTE: 'json:' can be used as struct tag key, in place 'codec:' below.
-//      type MyStruct struct {
-//          _struct bool    `codec:",omitempty"`   //set omitempty for every field
-//          Field1 string   `codec:"-"`            //skip this field
-//          Field2 int      `codec:"myName"`       //Use key "myName" in encode stream
-//          Field3 int32    `codec:",omitempty"`   //use key "Field3". Omit if empty.
-//          Field4 bool     `codec:"f4,omitempty"` //use key "f4". Omit if empty.
-//          io.Reader                              //use key "Reader".
-//          MyStruct        `codec:"my1"           //use key "my1".
-//          MyStruct                               //inline it
-//          ...
-//      }
-//
-//      type MyStruct struct {
-//          _struct bool    `codec:",toarray"`     //encode struct as an array
-//      }
-//
-//      type MyStruct struct {
-//          _struct bool    `codec:",uint"`        //encode struct with "unsigned integer" keys
-//          Field1 string   `codec:"1"`            //encode Field1 key using: EncodeInt(1)
-//          Field2 string   `codec:"2"`            //encode Field2 key using: EncodeInt(2)
-//      }
-//
-// The mode of encoding is based on the type of the value. When a value is seen:
-//   - If a Selfer, call its CodecEncodeSelf method
-//   - If an extension is registered for it, call that extension function
-//   - If implements encoding.(Binary|Text|JSON)Marshaler, call Marshal(Binary|Text|JSON) method
-//   - Else encode it based on its reflect.Kind
-//
-// Note that struct field names and keys in map[string]XXX will be treated as symbols.
-// Some formats support symbols (e.g. binc) and will properly encode the string
-// only once in the stream, and use a tag to refer to it thereafter.
-func (e *Encoder) Encode(v interface{}) (err error) {
-	// tried to use closure, as runtime optimizes defer with no params.
-	// This seemed to be causing weird issues (like circular reference found, unexpected panic, etc).
-	// Also, see https://github.com/golang/go/issues/14939#issuecomment-417836139
-	// defer func() { e.deferred(&err) }() }
-	// { x, y := e, &err; defer func() { x.deferred(y) }() }
-	if e.err != nil {
-		return e.err
-	}
-	if recoverPanicToErr {
-		defer func() {
-			e.w.end()
-			if x := recover(); x != nil {
-				panicValToErr(e, x, &e.err)
-				err = e.err
-			}
-		}()
-	}
-
-	// defer e.deferred(&err)
-	e.mustEncode(v)
-	return
-}
-
-// MustEncode is like Encode, but panics if unable to Encode.
-// This provides insight to the code location that triggered the error.
-func (e *Encoder) MustEncode(v interface{}) {
-	if e.err != nil {
-		panic(e.err)
-	}
-	e.mustEncode(v)
-}
-
-func (e *Encoder) mustEncode(v interface{}) {
-	if e.wf == nil {
-		e.encode(v)
-		e.e.atEndOfEncode()
-		e.w.end()
-		return
-	}
-
-	if e.wf.buf == nil {
-		e.wf.buf = e.wf.bytesBufPooler.get(e.wf.sz)
-	}
-	e.wf.calls++
-
-	e.encode(v)
-	e.e.atEndOfEncode()
-	e.w.end()
-
-	e.wf.calls--
-
-	if !e.h.ExplicitRelease && e.wf.calls == 0 {
-		e.wf.release()
-	}
-}
-
-// func (e *Encoder) deferred(err1 *error) {
-// 	e.w.end()
-// 	if recoverPanicToErr {
-// 		if x := recover(); x != nil {
-// 			panicValToErr(e, x, err1)
-// 			panicValToErr(e, x, &e.err)
-// 		}
-// 	}
-// }
-
-//go:noinline -- as it is run by finalizer
-func (e *Encoder) finalize() {
-	// xdebugf("finalizing Encoder")
-	e.Release()
-}
-
-// Release releases shared (pooled) resources.
-//
-// It is important to call Release() when done with an Encoder, so those resources
-// are released instantly for use by subsequently created Encoders.
-func (e *Encoder) Release() {
-	if e.wf != nil {
-		e.wf.release()
-	}
-}
-
-func (e *Encoder) encode(iv interface{}) {
-	// a switch with only concrete types can be optimized.
-	// consequently, we deal with nil and interfaces outside the switch.
-
-	if iv == nil || definitelyNil(iv) {
-		e.e.EncodeNil()
-		return
-	}
-
-	switch v := iv.(type) {
-	// case nil:
-	// case Selfer:
-	case Raw:
-		e.rawBytes(v)
-	case reflect.Value:
-		e.encodeValue(v, nil, true)
-
-	case string:
-		e.e.EncodeStringEnc(cUTF8, v)
-	case bool:
-		e.e.EncodeBool(v)
-	case int:
-		e.e.EncodeInt(int64(v))
-	case int8:
-		e.e.EncodeInt(int64(v))
-	case int16:
-		e.e.EncodeInt(int64(v))
-	case int32:
-		e.e.EncodeInt(int64(v))
-	case int64:
-		e.e.EncodeInt(v)
-	case uint:
-		e.e.EncodeUint(uint64(v))
-	case uint8:
-		e.e.EncodeUint(uint64(v))
-	case uint16:
-		e.e.EncodeUint(uint64(v))
-	case uint32:
-		e.e.EncodeUint(uint64(v))
-	case uint64:
-		e.e.EncodeUint(v)
-	case uintptr:
-		e.e.EncodeUint(uint64(v))
-	case float32:
-		e.e.EncodeFloat32(v)
-	case float64:
-		e.e.EncodeFloat64(v)
-	case time.Time:
-		e.e.EncodeTime(v)
-	case []uint8:
-		e.e.EncodeStringBytesRaw(v)
-
-	case *Raw:
-		e.rawBytes(*v)
-
-	case *string:
-		e.e.EncodeStringEnc(cUTF8, *v)
-	case *bool:
-		e.e.EncodeBool(*v)
-	case *int:
-		e.e.EncodeInt(int64(*v))
-	case *int8:
-		e.e.EncodeInt(int64(*v))
-	case *int16:
-		e.e.EncodeInt(int64(*v))
-	case *int32:
-		e.e.EncodeInt(int64(*v))
-	case *int64:
-		e.e.EncodeInt(*v)
-	case *uint:
-		e.e.EncodeUint(uint64(*v))
-	case *uint8:
-		e.e.EncodeUint(uint64(*v))
-	case *uint16:
-		e.e.EncodeUint(uint64(*v))
-	case *uint32:
-		e.e.EncodeUint(uint64(*v))
-	case *uint64:
-		e.e.EncodeUint(*v)
-	case *uintptr:
-		e.e.EncodeUint(uint64(*v))
-	case *float32:
-		e.e.EncodeFloat32(*v)
-	case *float64:
-		e.e.EncodeFloat64(*v)
-	case *time.Time:
-		e.e.EncodeTime(*v)
-
-	case *[]uint8:
-		e.e.EncodeStringBytesRaw(*v)
-
-	default:
-		if v, ok := iv.(Selfer); ok {
-			v.CodecEncodeSelf(e)
-		} else if !fastpathEncodeTypeSwitch(iv, e) {
-			// checkfastpath=true (not false), as underlying slice/map type may be fast-path
-			e.encodeValue(reflect.ValueOf(iv), nil, true)
-		}
-	}
-}
-
-func (e *Encoder) encodeValue(rv reflect.Value, fn *codecFn, checkFastpath bool) {
-	// if a valid fn is passed, it MUST BE for the dereferenced type of rv
-	var sptr uintptr
-	var rvp reflect.Value
-	var rvpValid bool
-TOP:
-	switch rv.Kind() {
-	case reflect.Ptr:
-		if rv.IsNil() {
-			e.e.EncodeNil()
-			return
-		}
-		rvpValid = true
-		rvp = rv
-		rv = rv.Elem()
-		if e.h.CheckCircularRef && rv.Kind() == reflect.Struct {
-			// TODO: Movable pointers will be an issue here. Future problem.
-			sptr = rv.UnsafeAddr()
-			break TOP
-		}
-		goto TOP
-	case reflect.Interface:
-		if rv.IsNil() {
-			e.e.EncodeNil()
-			return
-		}
-		rv = rv.Elem()
-		goto TOP
-	case reflect.Slice, reflect.Map:
-		if rv.IsNil() {
-			e.e.EncodeNil()
-			return
-		}
-	case reflect.Invalid, reflect.Func:
-		e.e.EncodeNil()
-		return
-	}
-
-	if sptr != 0 && (&e.ci).add(sptr) {
-		e.errorf("circular reference found: # %d", sptr)
-	}
-
-	if fn == nil {
-		rt := rv.Type()
-		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
-		fn = e.h.fn(rt, checkFastpath, true)
-	}
-	if fn.i.addrE {
-		if rvpValid {
-			fn.fe(e, &fn.i, rvp)
-		} else if rv.CanAddr() {
-			fn.fe(e, &fn.i, rv.Addr())
-		} else {
-			rv2 := reflect.New(rv.Type())
-			rv2.Elem().Set(rv)
-			fn.fe(e, &fn.i, rv2)
-		}
-	} else {
-		fn.fe(e, &fn.i, rv)
-	}
-	if sptr != 0 {
-		(&e.ci).remove(sptr)
-	}
-}
-
-// func (e *Encoder) marshal(bs []byte, fnerr error, asis bool, c charEncoding) {
-// 	if fnerr != nil {
-// 		panic(fnerr)
-// 	}
-// 	if bs == nil {
-// 		e.e.EncodeNil()
-// 	} else if asis {
-// 		e.asis(bs)
-// 	} else {
-// 		e.e.EncodeStringBytes(c, bs)
-// 	}
-// }
-
-func (e *Encoder) marshalUtf8(bs []byte, fnerr error) {
-	if fnerr != nil {
-		panic(fnerr)
-	}
-	if bs == nil {
-		e.e.EncodeNil()
-	} else {
-		e.e.EncodeStringEnc(cUTF8, stringView(bs))
-	}
-}
-
-func (e *Encoder) marshalAsis(bs []byte, fnerr error) {
-	if fnerr != nil {
-		panic(fnerr)
-	}
-	if bs == nil {
-		e.e.EncodeNil()
-	} else {
-		e.asis(bs)
-	}
-}
-
-func (e *Encoder) marshalRaw(bs []byte, fnerr error) {
-	if fnerr != nil {
-		panic(fnerr)
-	}
-	if bs == nil {
-		e.e.EncodeNil()
-	} else {
-		e.e.EncodeStringBytesRaw(bs)
-	}
-}
-
-func (e *Encoder) asis(v []byte) {
-	if e.isas {
-		e.as.EncodeAsis(v)
-	} else {
-		e.w.writeb(v)
-	}
-}
-
-func (e *Encoder) rawBytes(vv Raw) {
-	v := []byte(vv)
-	if !e.h.Raw {
-		e.errorf("Raw values cannot be encoded: %v", v)
-	}
-	e.asis(v)
-}
-
-func (e *Encoder) wrapErr(v interface{}, err *error) {
-	*err = encodeError{codecError{name: e.hh.Name(), err: v}}
-}

Some files were not shown because too many files changed in this diff