diff options
Diffstat (limited to 'vendor/github.com/json-iterator')
-rw-r--r-- | vendor/github.com/json-iterator/go/README.md | 15 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/adapter.go (renamed from vendor/github.com/json-iterator/go/feature_adapter.go) | 55 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any.go (renamed from vendor/github.com/json-iterator/go/feature_any.go) | 85 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_array.go (renamed from vendor/github.com/json-iterator/go/feature_any_array.go) | 0 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_bool.go (renamed from vendor/github.com/json-iterator/go/feature_any_bool.go) | 0 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_float.go (renamed from vendor/github.com/json-iterator/go/feature_any_float.go) | 0 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_int32.go (renamed from vendor/github.com/json-iterator/go/feature_any_int32.go) | 0 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_int64.go (renamed from vendor/github.com/json-iterator/go/feature_any_int64.go) | 0 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_invalid.go (renamed from vendor/github.com/json-iterator/go/feature_any_invalid.go) | 0 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_nil.go (renamed from vendor/github.com/json-iterator/go/feature_any_nil.go) | 0 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_number.go (renamed from vendor/github.com/json-iterator/go/feature_any_number.go) | 37 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_object.go (renamed from vendor/github.com/json-iterator/go/feature_any_object.go) | 0 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_str.go (renamed from vendor/github.com/json-iterator/go/feature_any_string.go) | 2 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_uint32.go (renamed from vendor/github.com/json-iterator/go/feature_any_uint32.go) | 0 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/any_uint64.go (renamed from vendor/github.com/json-iterator/go/feature_any_uint64.go) | 0 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/config.go | 375 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/feature_config.go | 312 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/feature_json_number.go | 15 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/feature_reflect.go | 691 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/feature_reflect_array.go | 99 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/feature_reflect_map.go | 244 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/feature_reflect_native.go | 672 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/feature_reflect_slice.go | 149 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/feature_stream_int.go | 320 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/iter.go (renamed from vendor/github.com/json-iterator/go/feature_iter.go) | 23 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/iter_array.go (renamed from vendor/github.com/json-iterator/go/feature_iter_array.go) | 6 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/iter_float.go (renamed from vendor/github.com/json-iterator/go/feature_iter_float.go) | 6 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/iter_int.go (renamed from vendor/github.com/json-iterator/go/feature_iter_int.go) | 87 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/iter_object.go (renamed from vendor/github.com/json-iterator/go/feature_iter_object.go) | 125 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/iter_skip.go (renamed from vendor/github.com/json-iterator/go/feature_iter_skip.go) | 6 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/iter_skip_sloppy.go (renamed from vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go) | 2 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/iter_skip_strict.go (renamed from vendor/github.com/json-iterator/go/feature_iter_skip_strict.go) | 4 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/iter_str.go (renamed from vendor/github.com/json-iterator/go/feature_iter_string.go) | 10 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/pool.go (renamed from vendor/github.com/json-iterator/go/feature_pool.go) | 37 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect.go | 332 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_array.go | 104 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_dynamic.go | 70 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_extension.go (renamed from vendor/github.com/json-iterator/go/feature_reflect_extension.go) | 298 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_json_number.go | 112 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_json_raw_message.go | 60 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_map.go | 326 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_marshaler.go | 218 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_native.go | 451 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_optional.go | 133 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_slice.go | 99 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_struct_decoder.go (renamed from vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go) | 528 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_struct_encoder.go (renamed from vendor/github.com/json-iterator/go/feature_reflect_object.go) | 158 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/stream.go (renamed from vendor/github.com/json-iterator/go/feature_stream.go) | 168 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/stream_float.go (renamed from vendor/github.com/json-iterator/go/feature_stream_float.go) | 14 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/stream_int.go | 190 | ||||
-rw-r--r-- | vendor/github.com/json-iterator/go/stream_str.go (renamed from vendor/github.com/json-iterator/go/feature_stream_string.go) | 40 |
51 files changed, 3504 insertions, 3174 deletions
diff --git a/vendor/github.com/json-iterator/go/README.md b/vendor/github.com/json-iterator/go/README.md index 23a4b57c8..54d5afe95 100644 --- a/vendor/github.com/json-iterator/go/README.md +++ b/vendor/github.com/json-iterator/go/README.md @@ -8,6 +8,8 @@ A high-performance 100% compatible drop-in replacement of "encoding/json" +You can also use thrift like JSON using [thrift-iterator](https://github.com/thrift-iterator/go) + ``` Go开发者们请加入我们,滴滴出行平台技术部 taowen@didichuxing.com ``` @@ -29,6 +31,9 @@ Raw Result (easyjson requires static code generation) | easyjson encode | 883 ns/op | 576 B/op | 3 allocs/op | | jsoniter encode | 837 ns/op | 384 B/op | 4 allocs/op | +Always benchmark with your own workload. +The result depends heavily on the data input. + # Usage 100% compatibility with standard lib @@ -44,7 +49,9 @@ with ```go import "github.com/json-iterator/go" -jsoniter.Marshal(&data) + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Marshal(&data) ``` Replace @@ -58,7 +65,9 @@ with ```go import "github.com/json-iterator/go" -jsoniter.Unmarshal(input, &data) + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Unmarshal(input, &data) ``` [More documentation](http://jsoniter.com/migrate-from-go-std.html) @@ -76,5 +85,7 @@ Contributors * [thockin](https://github.com/thockin) * [mattn](https://github.com/mattn) * [cch123](https://github.com/cch123) +* [Oleg Shaldybin](https://github.com/olegshaldybin) +* [Jason Toffaletti](https://github.com/toffaletti) Report issue or pull request, or email taowen@gmail.com, or [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) diff --git a/vendor/github.com/json-iterator/go/feature_adapter.go b/vendor/github.com/json-iterator/go/adapter.go index edb477c4f..e674d0f39 100644 --- a/vendor/github.com/json-iterator/go/feature_adapter.go +++ b/vendor/github.com/json-iterator/go/adapter.go @@ -16,15 +16,6 @@ func Unmarshal(data []byte, v interface{}) error { return ConfigDefault.Unmarshal(data, v) } -func lastNotSpacePos(data []byte) int { - for i := len(data) - 1; i >= 0; i-- { - if data[i] != ' ' && data[i] != '\t' && data[i] != '\r' && data[i] != '\n' { - return i + 1 - } - } - return 0 -} - // UnmarshalFromString convenient method to read from string instead of []byte func UnmarshalFromString(str string, v interface{}) error { return ConfigDefault.UnmarshalFromString(str, v) @@ -71,6 +62,11 @@ type Decoder struct { // 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 { @@ -81,7 +77,16 @@ func (adapter *Decoder) Decode(obj interface{}) error { // More is there more? func (adapter *Decoder) More() bool { - return adapter.iter.head != adapter.iter.tail + 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 @@ -90,11 +95,21 @@ func (adapter *Decoder) Buffered() io.Reader { return bytes.NewReader(remaining) } -// UseNumber for number JSON element, use float64 or json.NumberValue (alias of string) +// UseNumber causes the Decoder to unmarshal a number into an interface{} as a +// Number instead of as a float64. func (adapter *Decoder) UseNumber() { - origCfg := adapter.iter.cfg.configBeforeFrozen - origCfg.UseNumber = true - adapter.iter.cfg = origCfg.Froze().(*frozenConfig) + 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 @@ -110,18 +125,26 @@ type Encoder struct { // 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) { - adapter.stream.cfg.indentionStep = len(indent) + 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.Froze().(*frozenConfig) + 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) } diff --git a/vendor/github.com/json-iterator/go/feature_any.go b/vendor/github.com/json-iterator/go/any.go index 6733dce4c..daecfed61 100644 --- a/vendor/github.com/json-iterator/go/feature_any.go +++ b/vendor/github.com/json-iterator/go/any.go @@ -1,9 +1,13 @@ package jsoniter import ( + "errors" "fmt" + "github.com/modern-go/reflect2" "io" "reflect" + "strconv" + "unsafe" ) // Any generic object representation. @@ -24,7 +28,6 @@ type Any interface { ToString() string ToVal(val interface{}) Get(path ...interface{}) Any - // TODO: add Set Size() int Keys() []string GetInterface() interface{} @@ -34,7 +37,7 @@ type Any interface { type baseAny struct{} func (any *baseAny) Get(path ...interface{}) Any { - return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)} + return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} } func (any *baseAny) Size() int { @@ -88,7 +91,7 @@ func Wrap(val interface{}) Any { if isAny { return asAny } - typ := reflect.TypeOf(val) + typ := reflect2.TypeOf(val) switch typ.Kind() { case reflect.Slice: return wrapArray(val) @@ -99,6 +102,9 @@ func Wrap(val interface{}) Any { 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))) @@ -109,7 +115,15 @@ func Wrap(val interface{}) Any { 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: @@ -157,6 +171,8 @@ func (iter *Iterator) readAny() Any { return iter.readArrayAny() case '-': return iter.readNumberAny(false) + case 0: + return &invalidAny{baseAny{}, errors.New("input is empty")} default: return iter.readNumberAny(true) } @@ -240,3 +256,66 @@ func locatePath(iter *Iterator, path []interface{}) Any { } 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 +} diff --git a/vendor/github.com/json-iterator/go/feature_any_array.go b/vendor/github.com/json-iterator/go/any_array.go index 0449e9aa4..0449e9aa4 100644 --- a/vendor/github.com/json-iterator/go/feature_any_array.go +++ b/vendor/github.com/json-iterator/go/any_array.go diff --git a/vendor/github.com/json-iterator/go/feature_any_bool.go b/vendor/github.com/json-iterator/go/any_bool.go index 9452324af..9452324af 100644 --- a/vendor/github.com/json-iterator/go/feature_any_bool.go +++ b/vendor/github.com/json-iterator/go/any_bool.go diff --git a/vendor/github.com/json-iterator/go/feature_any_float.go b/vendor/github.com/json-iterator/go/any_float.go index 35fdb0949..35fdb0949 100644 --- a/vendor/github.com/json-iterator/go/feature_any_float.go +++ b/vendor/github.com/json-iterator/go/any_float.go diff --git a/vendor/github.com/json-iterator/go/feature_any_int32.go b/vendor/github.com/json-iterator/go/any_int32.go index 1b56f3991..1b56f3991 100644 --- a/vendor/github.com/json-iterator/go/feature_any_int32.go +++ b/vendor/github.com/json-iterator/go/any_int32.go diff --git a/vendor/github.com/json-iterator/go/feature_any_int64.go b/vendor/github.com/json-iterator/go/any_int64.go index c440d72b6..c440d72b6 100644 --- a/vendor/github.com/json-iterator/go/feature_any_int64.go +++ b/vendor/github.com/json-iterator/go/any_int64.go diff --git a/vendor/github.com/json-iterator/go/feature_any_invalid.go b/vendor/github.com/json-iterator/go/any_invalid.go index 1d859eac3..1d859eac3 100644 --- a/vendor/github.com/json-iterator/go/feature_any_invalid.go +++ b/vendor/github.com/json-iterator/go/any_invalid.go diff --git a/vendor/github.com/json-iterator/go/feature_any_nil.go b/vendor/github.com/json-iterator/go/any_nil.go index d04cb54c1..d04cb54c1 100644 --- a/vendor/github.com/json-iterator/go/feature_any_nil.go +++ b/vendor/github.com/json-iterator/go/any_nil.go diff --git a/vendor/github.com/json-iterator/go/feature_any_number.go b/vendor/github.com/json-iterator/go/any_number.go index 4e1c27641..9d1e901a6 100644 --- a/vendor/github.com/json-iterator/go/feature_any_number.go +++ b/vendor/github.com/json-iterator/go/any_number.go @@ -1,6 +1,9 @@ package jsoniter -import "unsafe" +import ( + "io" + "unsafe" +) type numberLazyAny struct { baseAny @@ -29,7 +32,9 @@ func (any *numberLazyAny) ToInt() int { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadInt() - any.err = iter.Error + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } return val } @@ -37,7 +42,9 @@ func (any *numberLazyAny) ToInt32() int32 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadInt32() - any.err = iter.Error + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } return val } @@ -45,7 +52,9 @@ func (any *numberLazyAny) ToInt64() int64 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadInt64() - any.err = iter.Error + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } return val } @@ -53,7 +62,9 @@ func (any *numberLazyAny) ToUint() uint { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadUint() - any.err = iter.Error + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } return val } @@ -61,7 +72,9 @@ func (any *numberLazyAny) ToUint32() uint32 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadUint32() - any.err = iter.Error + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } return val } @@ -69,7 +82,9 @@ func (any *numberLazyAny) ToUint64() uint64 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadUint64() - any.err = iter.Error + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } return val } @@ -77,7 +92,9 @@ func (any *numberLazyAny) ToFloat32() float32 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadFloat32() - any.err = iter.Error + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } return val } @@ -85,7 +102,9 @@ func (any *numberLazyAny) ToFloat64() float64 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadFloat64() - any.err = iter.Error + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } return val } diff --git a/vendor/github.com/json-iterator/go/feature_any_object.go b/vendor/github.com/json-iterator/go/any_object.go index c44ef5c98..c44ef5c98 100644 --- a/vendor/github.com/json-iterator/go/feature_any_object.go +++ b/vendor/github.com/json-iterator/go/any_object.go diff --git a/vendor/github.com/json-iterator/go/feature_any_string.go b/vendor/github.com/json-iterator/go/any_str.go index abf060bd5..a4b93c78c 100644 --- a/vendor/github.com/json-iterator/go/feature_any_string.go +++ b/vendor/github.com/json-iterator/go/any_str.go @@ -14,7 +14,7 @@ func (any *stringAny) Get(path ...interface{}) Any { if len(path) == 0 { return any } - return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)} + return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} } func (any *stringAny) Parse() *Iterator { diff --git a/vendor/github.com/json-iterator/go/feature_any_uint32.go b/vendor/github.com/json-iterator/go/any_uint32.go index 656bbd33d..656bbd33d 100644 --- a/vendor/github.com/json-iterator/go/feature_any_uint32.go +++ b/vendor/github.com/json-iterator/go/any_uint32.go diff --git a/vendor/github.com/json-iterator/go/feature_any_uint64.go b/vendor/github.com/json-iterator/go/any_uint64.go index 7df2fce33..7df2fce33 100644 --- a/vendor/github.com/json-iterator/go/feature_any_uint64.go +++ b/vendor/github.com/json-iterator/go/any_uint64.go diff --git a/vendor/github.com/json-iterator/go/config.go b/vendor/github.com/json-iterator/go/config.go new file mode 100644 index 000000000..8c58fcba5 --- /dev/null +++ b/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 +} diff --git a/vendor/github.com/json-iterator/go/feature_config.go b/vendor/github.com/json-iterator/go/feature_config.go deleted file mode 100644 index fc055d504..000000000 --- a/vendor/github.com/json-iterator/go/feature_config.go +++ /dev/null @@ -1,312 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "errors" - "io" - "reflect" - "sync/atomic" - "unsafe" -) - -// 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 - TagKey string -} - -type frozenConfig struct { - configBeforeFrozen Config - sortMapKeys bool - indentionStep int - decoderCache unsafe.Pointer - encoderCache unsafe.Pointer - extensions []Extension - streamPool chan *Stream - iteratorPool chan *Iterator -} - -// 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 -} - -// 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, -}.Froze() - -// ConfigFastest marshals float with only 6 digits precision -var ConfigFastest = Config{ - EscapeHTML: false, - MarshalFloatWith6Digits: true, -}.Froze() - -// Froze forge API from config -func (cfg Config) Froze() API { - // TODO: cache frozen config - frozenConfig := &frozenConfig{ - sortMapKeys: cfg.SortMapKeys, - indentionStep: cfg.IndentionStep, - streamPool: make(chan *Stream, 16), - iteratorPool: make(chan *Iterator, 16), - } - atomic.StorePointer(&frozenConfig.decoderCache, unsafe.Pointer(&map[string]ValDecoder{})) - atomic.StorePointer(&frozenConfig.encoderCache, unsafe.Pointer(&map[string]ValEncoder{})) - if cfg.MarshalFloatWith6Digits { - frozenConfig.marshalFloatWith6Digits() - } - if cfg.EscapeHTML { - frozenConfig.escapeHTML() - } - if cfg.UseNumber { - frozenConfig.useNumber() - } - frozenConfig.configBeforeFrozen = cfg - return frozenConfig -} - -func (cfg *frozenConfig) useNumber() { - cfg.addDecoderToCache(reflect.TypeOf((*interface{})(nil)).Elem(), &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { - 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.extensions = append(cfg.extensions, extension) -} - -type lossyFloat32Encoder struct { -} - -func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat32Lossy(*((*float32)(ptr))) -} - -func (encoder *lossyFloat32Encoder) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -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) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -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() { - // for better performance - cfg.addEncoderToCache(reflect.TypeOf((*float32)(nil)).Elem(), &lossyFloat32Encoder{}) - cfg.addEncoderToCache(reflect.TypeOf((*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) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return *((*string)(ptr)) == "" -} - -func (cfg *frozenConfig) escapeHTML() { - cfg.addEncoderToCache(reflect.TypeOf((*string)(nil)).Elem(), &htmlEscapedStringEncoder{}) -} - -func (cfg *frozenConfig) addDecoderToCache(cacheKey reflect.Type, decoder ValDecoder) { - done := false - for !done { - ptr := atomic.LoadPointer(&cfg.decoderCache) - cache := *(*map[reflect.Type]ValDecoder)(ptr) - copied := map[reflect.Type]ValDecoder{} - for k, v := range cache { - copied[k] = v - } - copied[cacheKey] = decoder - done = atomic.CompareAndSwapPointer(&cfg.decoderCache, ptr, unsafe.Pointer(&copied)) - } -} - -func (cfg *frozenConfig) addEncoderToCache(cacheKey reflect.Type, encoder ValEncoder) { - done := false - for !done { - ptr := atomic.LoadPointer(&cfg.encoderCache) - cache := *(*map[reflect.Type]ValEncoder)(ptr) - copied := map[reflect.Type]ValEncoder{} - for k, v := range cache { - copied[k] = v - } - copied[cacheKey] = encoder - done = atomic.CompareAndSwapPointer(&cfg.encoderCache, ptr, unsafe.Pointer(&copied)) - } -} - -func (cfg *frozenConfig) getDecoderFromCache(cacheKey reflect.Type) ValDecoder { - ptr := atomic.LoadPointer(&cfg.decoderCache) - cache := *(*map[reflect.Type]ValDecoder)(ptr) - return cache[cacheKey] -} - -func (cfg *frozenConfig) getEncoderFromCache(cacheKey reflect.Type) ValEncoder { - ptr := atomic.LoadPointer(&cfg.encoderCache) - cache := *(*map[reflect.Type]ValEncoder)(ptr) - return cache[cacheKey] -} - -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.Froze().Marshal(v) -} - -func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error { - data := []byte(str) - data = data[:lastNotSpacePos(data)] - iter := cfg.BorrowIterator(data) - defer cfg.ReturnIterator(iter) - iter.ReadVal(v) - if iter.head == iter.tail { - iter.loadMore() - } - if iter.Error == io.EOF { - return nil - } - if iter.Error == nil { - iter.ReportError("UnmarshalFromString", "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 { - data = data[:lastNotSpacePos(data)] - iter := cfg.BorrowIterator(data) - defer cfg.ReturnIterator(iter) - typ := reflect.TypeOf(v) - if typ.Kind() != reflect.Ptr { - // return non-pointer error - return errors.New("the second param must be ptr type") - } - iter.ReadVal(v) - if iter.head == iter.tail { - iter.loadMore() - } - if iter.Error == io.EOF { - return nil - } - if iter.Error == nil { - 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} -} diff --git a/vendor/github.com/json-iterator/go/feature_json_number.go b/vendor/github.com/json-iterator/go/feature_json_number.go deleted file mode 100644 index 0439f6725..000000000 --- a/vendor/github.com/json-iterator/go/feature_json_number.go +++ /dev/null @@ -1,15 +0,0 @@ -package jsoniter - -import "encoding/json" - -type Number string - -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 -} diff --git a/vendor/github.com/json-iterator/go/feature_reflect.go b/vendor/github.com/json-iterator/go/feature_reflect.go deleted file mode 100644 index 05d91b49c..000000000 --- a/vendor/github.com/json-iterator/go/feature_reflect.go +++ /dev/null @@ -1,691 +0,0 @@ -package jsoniter - -import ( - "encoding" - "encoding/json" - "fmt" - "reflect" - "time" - "unsafe" -) - -// 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) - EncodeInterface(val interface{}, stream *Stream) -} - -type checkIsEmpty interface { - IsEmpty(ptr unsafe.Pointer) bool -} - -// WriteToStream the default implementation for TypeEncoder method EncodeInterface -func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) { - e := (*emptyInterface)(unsafe.Pointer(&val)) - if e.word == nil { - stream.WriteNil() - return - } - if reflect.TypeOf(val).Kind() == reflect.Ptr { - encoder.Encode(unsafe.Pointer(&e.word), stream) - } else { - encoder.Encode(e.word, stream) - } -} - -var jsonNumberType reflect.Type -var jsoniterNumberType reflect.Type -var jsonRawMessageType reflect.Type -var jsoniterRawMessageType reflect.Type -var anyType reflect.Type -var marshalerType reflect.Type -var unmarshalerType reflect.Type -var textMarshalerType reflect.Type -var textUnmarshalerType reflect.Type - -func init() { - jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem() - jsoniterNumberType = reflect.TypeOf((*Number)(nil)).Elem() - jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem() - jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem() - anyType = reflect.TypeOf((*Any)(nil)).Elem() - marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem() - unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() - textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() - textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() -} - -type optionalDecoder struct { - valueType reflect.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 - value := reflect.New(decoder.valueType) - newPtr := extractInterface(value.Interface()).word - decoder.valueDecoder.Decode(newPtr, iter) - *((*uintptr)(ptr)) = uintptr(newPtr) - } else { - //reuse existing instance - decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) - } - } -} - -type deferenceDecoder struct { - // only to deference a pointer - valueType reflect.Type - valueDecoder ValDecoder -} - -func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if *((*unsafe.Pointer)(ptr)) == nil { - //pointer to null, we have to allocate memory to hold the value - value := reflect.New(decoder.valueType) - newPtr := extractInterface(value.Interface()).word - decoder.valueDecoder.Decode(newPtr, iter) - *((*uintptr)(ptr)) = uintptr(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) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { - if *((*unsafe.Pointer)(ptr)) == nil { - return true - } - return false -} - -type placeholderEncoder struct { - cfg *frozenConfig - cacheKey reflect.Type -} - -func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - encoder.getRealEncoder().Encode(ptr, stream) -} - -func (encoder *placeholderEncoder) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.getRealEncoder().IsEmpty(ptr) -} - -func (encoder *placeholderEncoder) getRealEncoder() ValEncoder { - for i := 0; i < 30; i++ { - realDecoder := encoder.cfg.getEncoderFromCache(encoder.cacheKey) - _, isPlaceholder := realDecoder.(*placeholderEncoder) - if isPlaceholder { - time.Sleep(time.Second) - } else { - return realDecoder - } - } - panic(fmt.Sprintf("real encoder not found for cache key: %v", encoder.cacheKey)) -} - -type placeholderDecoder struct { - cfg *frozenConfig - cacheKey reflect.Type -} - -func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - for i := 0; i < 30; i++ { - realDecoder := decoder.cfg.getDecoderFromCache(decoder.cacheKey) - _, isPlaceholder := realDecoder.(*placeholderDecoder) - if isPlaceholder { - time.Sleep(time.Second) - } else { - realDecoder.Decode(ptr, iter) - return - } - } - panic(fmt.Sprintf("real decoder not found for cache key: %v", decoder.cacheKey)) -} - -// emptyInterface is the header for an interface{} value. -type emptyInterface struct { - typ unsafe.Pointer - word unsafe.Pointer -} - -// emptyInterface is the header for an interface with method (not interface{}) -type nonEmptyInterface struct { - // see ../runtime/iface.go:/Itab - itab *struct { - ityp unsafe.Pointer // static interface type - typ unsafe.Pointer // dynamic concrete type - link unsafe.Pointer - bad int32 - unused int32 - fun [100000]unsafe.Pointer // method table - } - word unsafe.Pointer -} - -// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal -func (iter *Iterator) ReadVal(obj interface{}) { - typ := reflect.TypeOf(obj) - cacheKey := typ.Elem() - decoder, err := decoderOfType(iter.cfg, cacheKey) - if err != nil { - iter.Error = err - return - } - e := (*emptyInterface)(unsafe.Pointer(&obj)) - decoder.Decode(e.word, 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 - } - typ := reflect.TypeOf(val) - cacheKey := typ - encoder, err := encoderOfType(stream.cfg, cacheKey) - if err != nil { - stream.Error = err - return - } - encoder.EncodeInterface(val, stream) -} - -type prefix string - -func (p prefix) addToDecoder(decoder ValDecoder, err error) (ValDecoder, error) { - if err != nil { - return nil, fmt.Errorf("%s: %s", p, err.Error()) - } - return decoder, err -} - -func (p prefix) addToEncoder(encoder ValEncoder, err error) (ValEncoder, error) { - if err != nil { - return nil, fmt.Errorf("%s: %s", p, err.Error()) - } - return encoder, err -} - -func decoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { - cacheKey := typ - decoder := cfg.getDecoderFromCache(cacheKey) - if decoder != nil { - return decoder, nil - } - decoder = getTypeDecoderFromExtension(typ) - if decoder != nil { - cfg.addDecoderToCache(cacheKey, decoder) - return decoder, nil - } - decoder = &placeholderDecoder{cfg: cfg, cacheKey: cacheKey} - cfg.addDecoderToCache(cacheKey, decoder) - decoder, err := createDecoderOfType(cfg, typ) - for _, extension := range extensions { - decoder = extension.DecorateDecoder(typ, decoder) - } - cfg.addDecoderToCache(cacheKey, decoder) - return decoder, err -} - -func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { - typeName := typ.String() - if typ == jsonRawMessageType { - return &jsonRawMessageCodec{}, nil - } - if typ == jsoniterRawMessageType { - return &jsoniterRawMessageCodec{}, nil - } - if typ.AssignableTo(jsonNumberType) { - return &jsonNumberCodec{}, nil - } - if typ.AssignableTo(jsoniterNumberType) { - return &jsoniterNumberCodec{}, nil - } - if typ.Implements(unmarshalerType) { - templateInterface := reflect.New(typ).Elem().Interface() - var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)} - if typ.Kind() == reflect.Ptr { - decoder = &optionalDecoder{typ.Elem(), decoder} - } - return decoder, nil - } - if reflect.PtrTo(typ).Implements(unmarshalerType) { - templateInterface := reflect.New(typ).Interface() - var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)} - return decoder, nil - } - if typ.Implements(textUnmarshalerType) { - templateInterface := reflect.New(typ).Elem().Interface() - var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)} - if typ.Kind() == reflect.Ptr { - decoder = &optionalDecoder{typ.Elem(), decoder} - } - return decoder, nil - } - if reflect.PtrTo(typ).Implements(textUnmarshalerType) { - templateInterface := reflect.New(typ).Interface() - var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)} - return decoder, nil - } - if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { - sliceDecoder, err := prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ)) - if err != nil { - return nil, err - } - return &base64Codec{sliceDecoder: sliceDecoder}, nil - } - if typ.Implements(anyType) { - return &anyCodec{}, nil - } - switch typ.Kind() { - case reflect.String: - if typeName != "string" { - return decoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem()) - } - return &stringCodec{}, nil - case reflect.Int: - if typeName != "int" { - return decoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem()) - } - return &intCodec{}, nil - case reflect.Int8: - if typeName != "int8" { - return decoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem()) - } - return &int8Codec{}, nil - case reflect.Int16: - if typeName != "int16" { - return decoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem()) - } - return &int16Codec{}, nil - case reflect.Int32: - if typeName != "int32" { - return decoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem()) - } - return &int32Codec{}, nil - case reflect.Int64: - if typeName != "int64" { - return decoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem()) - } - return &int64Codec{}, nil - case reflect.Uint: - if typeName != "uint" { - return decoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem()) - } - return &uintCodec{}, nil - case reflect.Uint8: - if typeName != "uint8" { - return decoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem()) - } - return &uint8Codec{}, nil - case reflect.Uint16: - if typeName != "uint16" { - return decoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem()) - } - return &uint16Codec{}, nil - case reflect.Uint32: - if typeName != "uint32" { - return decoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem()) - } - return &uint32Codec{}, nil - case reflect.Uintptr: - if typeName != "uintptr" { - return decoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem()) - } - return &uintptrCodec{}, nil - case reflect.Uint64: - if typeName != "uint64" { - return decoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem()) - } - return &uint64Codec{}, nil - case reflect.Float32: - if typeName != "float32" { - return decoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem()) - } - return &float32Codec{}, nil - case reflect.Float64: - if typeName != "float64" { - return decoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem()) - } - return &float64Codec{}, nil - case reflect.Bool: - if typeName != "bool" { - return decoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem()) - } - return &boolCodec{}, nil - case reflect.Interface: - if typ.NumMethod() == 0 { - return &emptyInterfaceCodec{}, nil - } - return &nonEmptyInterfaceCodec{}, nil - case reflect.Struct: - return prefix(fmt.Sprintf("[%s]", typeName)).addToDecoder(decoderOfStruct(cfg, typ)) - case reflect.Array: - return prefix("[array]").addToDecoder(decoderOfArray(cfg, typ)) - case reflect.Slice: - return prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ)) - case reflect.Map: - return prefix("[map]").addToDecoder(decoderOfMap(cfg, typ)) - case reflect.Ptr: - return prefix("[optional]").addToDecoder(decoderOfOptional(cfg, typ)) - default: - return nil, fmt.Errorf("unsupported type: %v", typ) - } -} - -func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { - cacheKey := typ - encoder := cfg.getEncoderFromCache(cacheKey) - if encoder != nil { - return encoder, nil - } - encoder = getTypeEncoderFromExtension(typ) - if encoder != nil { - cfg.addEncoderToCache(cacheKey, encoder) - return encoder, nil - } - encoder = &placeholderEncoder{cfg: cfg, cacheKey: cacheKey} - cfg.addEncoderToCache(cacheKey, encoder) - encoder, err := createEncoderOfType(cfg, typ) - for _, extension := range extensions { - encoder = extension.DecorateEncoder(typ, encoder) - } - cfg.addEncoderToCache(cacheKey, encoder) - return encoder, err -} - -func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { - if typ == jsonRawMessageType { - return &jsonRawMessageCodec{}, nil - } - if typ == jsoniterRawMessageType { - return &jsoniterRawMessageCodec{}, nil - } - if typ.AssignableTo(jsonNumberType) { - return &jsonNumberCodec{}, nil - } - if typ.AssignableTo(jsoniterNumberType) { - return &jsoniterNumberCodec{}, nil - } - if typ.Implements(marshalerType) { - checkIsEmpty, err := createCheckIsEmpty(typ) - if err != nil { - return nil, err - } - templateInterface := reflect.New(typ).Elem().Interface() - var encoder ValEncoder = &marshalerEncoder{ - templateInterface: extractInterface(templateInterface), - checkIsEmpty: checkIsEmpty, - } - if typ.Kind() == reflect.Ptr { - encoder = &optionalEncoder{encoder} - } - return encoder, nil - } - if typ.Implements(textMarshalerType) { - checkIsEmpty, err := createCheckIsEmpty(typ) - if err != nil { - return nil, err - } - templateInterface := reflect.New(typ).Elem().Interface() - var encoder ValEncoder = &textMarshalerEncoder{ - templateInterface: extractInterface(templateInterface), - checkIsEmpty: checkIsEmpty, - } - if typ.Kind() == reflect.Ptr { - encoder = &optionalEncoder{encoder} - } - return encoder, nil - } - if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { - return &base64Codec{}, nil - } - if typ.Implements(anyType) { - return &anyCodec{}, nil - } - return createEncoderOfSimpleType(cfg, typ) -} - -func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) { - kind := typ.Kind() - switch kind { - case reflect.String: - return &stringCodec{}, nil - case reflect.Int: - return &intCodec{}, nil - case reflect.Int8: - return &int8Codec{}, nil - case reflect.Int16: - return &int16Codec{}, nil - case reflect.Int32: - return &int32Codec{}, nil - case reflect.Int64: - return &int64Codec{}, nil - case reflect.Uint: - return &uintCodec{}, nil - case reflect.Uint8: - return &uint8Codec{}, nil - case reflect.Uint16: - return &uint16Codec{}, nil - case reflect.Uint32: - return &uint32Codec{}, nil - case reflect.Uintptr: - return &uintptrCodec{}, nil - case reflect.Uint64: - return &uint64Codec{}, nil - case reflect.Float32: - return &float32Codec{}, nil - case reflect.Float64: - return &float64Codec{}, nil - case reflect.Bool: - return &boolCodec{}, nil - case reflect.Interface: - if typ.NumMethod() == 0 { - return &emptyInterfaceCodec{}, nil - } - return &nonEmptyInterfaceCodec{}, nil - case reflect.Struct: - return &structEncoder{}, nil - case reflect.Array: - return &arrayEncoder{}, nil - case reflect.Slice: - return &sliceEncoder{}, nil - case reflect.Map: - return &mapEncoder{}, nil - case reflect.Ptr: - return &optionalEncoder{}, nil - default: - return nil, fmt.Errorf("unsupported type: %v", typ) - } -} - -func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { - typeName := typ.String() - kind := typ.Kind() - switch kind { - case reflect.String: - if typeName != "string" { - return encoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem()) - } - return &stringCodec{}, nil - case reflect.Int: - if typeName != "int" { - return encoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem()) - } - return &intCodec{}, nil - case reflect.Int8: - if typeName != "int8" { - return encoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem()) - } - return &int8Codec{}, nil - case reflect.Int16: - if typeName != "int16" { - return encoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem()) - } - return &int16Codec{}, nil - case reflect.Int32: - if typeName != "int32" { - return encoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem()) - } - return &int32Codec{}, nil - case reflect.Int64: - if typeName != "int64" { - return encoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem()) - } - return &int64Codec{}, nil - case reflect.Uint: - if typeName != "uint" { - return encoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem()) - } - return &uintCodec{}, nil - case reflect.Uint8: - if typeName != "uint8" { - return encoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem()) - } - return &uint8Codec{}, nil - case reflect.Uint16: - if typeName != "uint16" { - return encoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem()) - } - return &uint16Codec{}, nil - case reflect.Uint32: - if typeName != "uint32" { - return encoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem()) - } - return &uint32Codec{}, nil - case reflect.Uintptr: - if typeName != "uintptr" { - return encoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem()) - } - return &uintptrCodec{}, nil - case reflect.Uint64: - if typeName != "uint64" { - return encoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem()) - } - return &uint64Codec{}, nil - case reflect.Float32: - if typeName != "float32" { - return encoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem()) - } - return &float32Codec{}, nil - case reflect.Float64: - if typeName != "float64" { - return encoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem()) - } - return &float64Codec{}, nil - case reflect.Bool: - if typeName != "bool" { - return encoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem()) - } - return &boolCodec{}, nil - case reflect.Interface: - if typ.NumMethod() == 0 { - return &emptyInterfaceCodec{}, nil - } - return &nonEmptyInterfaceCodec{}, nil - case reflect.Struct: - return prefix(fmt.Sprintf("[%s]", typeName)).addToEncoder(encoderOfStruct(cfg, typ)) - case reflect.Array: - return prefix("[array]").addToEncoder(encoderOfArray(cfg, typ)) - case reflect.Slice: - return prefix("[slice]").addToEncoder(encoderOfSlice(cfg, typ)) - case reflect.Map: - return prefix("[map]").addToEncoder(encoderOfMap(cfg, typ)) - case reflect.Ptr: - return prefix("[optional]").addToEncoder(encoderOfOptional(cfg, typ)) - default: - return nil, fmt.Errorf("unsupported type: %v", typ) - } -} - -func decoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { - elemType := typ.Elem() - decoder, err := decoderOfType(cfg, elemType) - if err != nil { - return nil, err - } - return &optionalDecoder{elemType, decoder}, nil -} - -func encoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { - elemType := typ.Elem() - elemEncoder, err := encoderOfType(cfg, elemType) - if err != nil { - return nil, err - } - encoder := &optionalEncoder{elemEncoder} - if elemType.Kind() == reflect.Map { - encoder = &optionalEncoder{encoder} - } - return encoder, nil -} - -func decoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { - decoder, err := decoderOfType(cfg, typ.Elem()) - if err != nil { - return nil, err - } - mapInterface := reflect.New(typ).Interface() - return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}, nil -} - -func extractInterface(val interface{}) emptyInterface { - return *((*emptyInterface)(unsafe.Pointer(&val))) -} - -func encoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { - elemType := typ.Elem() - encoder, err := encoderOfType(cfg, elemType) - if err != nil { - return nil, err - } - mapInterface := reflect.New(typ).Elem().Interface() - if cfg.sortMapKeys { - return &sortKeysMapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil - } - return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil -} diff --git a/vendor/github.com/json-iterator/go/feature_reflect_array.go b/vendor/github.com/json-iterator/go/feature_reflect_array.go deleted file mode 100644 index e23f187b7..000000000 --- a/vendor/github.com/json-iterator/go/feature_reflect_array.go +++ /dev/null @@ -1,99 +0,0 @@ -package jsoniter - -import ( - "fmt" - "io" - "reflect" - "unsafe" -) - -func decoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { - decoder, err := decoderOfType(cfg, typ.Elem()) - if err != nil { - return nil, err - } - return &arrayDecoder{typ, typ.Elem(), decoder}, nil -} - -func encoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { - encoder, err := encoderOfType(cfg, typ.Elem()) - if err != nil { - return nil, err - } - if typ.Elem().Kind() == reflect.Map { - encoder = &optionalEncoder{encoder} - } - return &arrayEncoder{typ, typ.Elem(), encoder}, nil -} - -type arrayEncoder struct { - arrayType reflect.Type - elemType reflect.Type - 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 = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size()) - encoder.elemEncoder.Encode(unsafe.Pointer(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) EncodeInterface(val interface{}, stream *Stream) { - // special optimization for interface{} - e := (*emptyInterface)(unsafe.Pointer(&val)) - if e.word == nil { - stream.WriteArrayStart() - stream.WriteNil() - stream.WriteArrayEnd() - return - } - elemType := encoder.arrayType.Elem() - if encoder.arrayType.Len() == 1 && (elemType.Kind() == reflect.Ptr || elemType.Kind() == reflect.Map) { - ptr := uintptr(e.word) - e.word = unsafe.Pointer(&ptr) - } - if reflect.TypeOf(val).Kind() == reflect.Ptr { - encoder.Encode(unsafe.Pointer(&e.word), stream) - } else { - encoder.Encode(e.word, stream) - } -} - -func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type arrayDecoder struct { - arrayType reflect.Type - elemType reflect.Type - 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) { - offset := uintptr(0) - iter.ReadArrayCB(func(iter *Iterator) bool { - if offset < decoder.arrayType.Size() { - decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(ptr)+offset), iter) - offset += decoder.elemType.Size() - } else { - iter.Skip() - } - return true - }) -} diff --git a/vendor/github.com/json-iterator/go/feature_reflect_map.go b/vendor/github.com/json-iterator/go/feature_reflect_map.go deleted file mode 100644 index 005671e01..000000000 --- a/vendor/github.com/json-iterator/go/feature_reflect_map.go +++ /dev/null @@ -1,244 +0,0 @@ -package jsoniter - -import ( - "encoding" - "encoding/json" - "reflect" - "sort" - "strconv" - "unsafe" -) - -type mapDecoder struct { - mapType reflect.Type - keyType reflect.Type - elemType reflect.Type - elemDecoder ValDecoder - mapInterface emptyInterface -} - -func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - // dark magic to cast unsafe.Pointer back to interface{} using reflect.Type - mapInterface := decoder.mapInterface - mapInterface.word = ptr - realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) - realVal := reflect.ValueOf(*realInterface).Elem() - if iter.ReadNil() { - realVal.Set(reflect.Zero(decoder.mapType)) - return - } - if realVal.IsNil() { - realVal.Set(reflect.MakeMap(realVal.Type())) - } - iter.ReadMapCB(func(iter *Iterator, keyStr string) bool { - elem := reflect.New(decoder.elemType) - decoder.elemDecoder.Decode(unsafe.Pointer(elem.Pointer()), iter) - // to put into map, we have to use reflection - keyType := decoder.keyType - // TODO: remove this from loop - switch { - case keyType.Kind() == reflect.String: - realVal.SetMapIndex(reflect.ValueOf(keyStr).Convert(keyType), elem.Elem()) - return true - case keyType.Implements(textUnmarshalerType): - textUnmarshaler := reflect.New(keyType.Elem()).Interface().(encoding.TextUnmarshaler) - err := textUnmarshaler.UnmarshalText([]byte(keyStr)) - if err != nil { - iter.ReportError("read map key as TextUnmarshaler", err.Error()) - return false - } - realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler), elem.Elem()) - return true - case reflect.PtrTo(keyType).Implements(textUnmarshalerType): - textUnmarshaler := reflect.New(keyType).Interface().(encoding.TextUnmarshaler) - err := textUnmarshaler.UnmarshalText([]byte(keyStr)) - if err != nil { - iter.ReportError("read map key as TextUnmarshaler", err.Error()) - return false - } - realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler).Elem(), elem.Elem()) - return true - default: - switch keyType.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - n, err := strconv.ParseInt(keyStr, 10, 64) - if err != nil || reflect.Zero(keyType).OverflowInt(n) { - iter.ReportError("read map key as int64", "read int64 failed") - return false - } - realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem()) - return true - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - n, err := strconv.ParseUint(keyStr, 10, 64) - if err != nil || reflect.Zero(keyType).OverflowUint(n) { - iter.ReportError("read map key as uint64", "read uint64 failed") - return false - } - realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem()) - return true - } - } - iter.ReportError("read map key", "unexpected map key type "+keyType.String()) - return true - }) -} - -type mapEncoder struct { - mapType reflect.Type - elemType reflect.Type - elemEncoder ValEncoder - mapInterface emptyInterface -} - -func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - mapInterface := encoder.mapInterface - mapInterface.word = ptr - realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) - realVal := reflect.ValueOf(*realInterface) - stream.WriteObjectStart() - for i, key := range realVal.MapKeys() { - if i != 0 { - stream.WriteMore() - } - encodeMapKey(key, stream) - if stream.indention > 0 { - stream.writeTwoBytes(byte(':'), byte(' ')) - } else { - stream.writeByte(':') - } - val := realVal.MapIndex(key).Interface() - encoder.elemEncoder.EncodeInterface(val, stream) - } - stream.WriteObjectEnd() -} - -func encodeMapKey(key reflect.Value, stream *Stream) { - if key.Kind() == reflect.String { - stream.WriteString(key.String()) - return - } - if tm, ok := key.Interface().(encoding.TextMarshaler); ok { - buf, err := tm.MarshalText() - if err != nil { - stream.Error = err - return - } - stream.writeByte('"') - stream.Write(buf) - stream.writeByte('"') - return - } - switch key.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - stream.writeByte('"') - stream.WriteInt64(key.Int()) - stream.writeByte('"') - return - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - stream.writeByte('"') - stream.WriteUint64(key.Uint()) - stream.writeByte('"') - return - } - stream.Error = &json.UnsupportedTypeError{Type: key.Type()} -} - -func (encoder *mapEncoder) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool { - mapInterface := encoder.mapInterface - mapInterface.word = ptr - realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) - realVal := reflect.ValueOf(*realInterface) - return realVal.Len() == 0 -} - -type sortKeysMapEncoder struct { - mapType reflect.Type - elemType reflect.Type - elemEncoder ValEncoder - mapInterface emptyInterface -} - -func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - mapInterface := encoder.mapInterface - mapInterface.word = ptr - realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) - realVal := reflect.ValueOf(*realInterface) - - // Extract and sort the keys. - keys := realVal.MapKeys() - sv := stringValues(make([]reflectWithString, len(keys))) - for i, v := range keys { - sv[i].v = v - if err := sv[i].resolve(); err != nil { - stream.Error = err - return - } - } - sort.Sort(sv) - - stream.WriteObjectStart() - for i, key := range sv { - if i != 0 { - stream.WriteMore() - } - stream.WriteVal(key.s) // might need html escape, so can not WriteString directly - if stream.indention > 0 { - stream.writeTwoBytes(byte(':'), byte(' ')) - } else { - stream.writeByte(':') - } - val := realVal.MapIndex(key.v).Interface() - encoder.elemEncoder.EncodeInterface(val, stream) - } - stream.WriteObjectEnd() -} - -// stringValues is a slice of reflect.Value holding *reflect.StringValue. -// It implements the methods to sort by string. -type stringValues []reflectWithString - -type reflectWithString struct { - v reflect.Value - s string -} - -func (w *reflectWithString) resolve() error { - if w.v.Kind() == reflect.String { - w.s = w.v.String() - return nil - } - if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok { - buf, err := tm.MarshalText() - w.s = string(buf) - return err - } - switch w.v.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - w.s = strconv.FormatInt(w.v.Int(), 10) - return nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - w.s = strconv.FormatUint(w.v.Uint(), 10) - return nil - } - return &json.UnsupportedTypeError{Type: w.v.Type()} -} - -func (sv stringValues) Len() int { return len(sv) } -func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } -func (sv stringValues) Less(i, j int) bool { return sv[i].s < sv[j].s } - -func (encoder *sortKeysMapEncoder) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { - mapInterface := encoder.mapInterface - mapInterface.word = ptr - realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) - realVal := reflect.ValueOf(*realInterface) - return realVal.Len() == 0 -} diff --git a/vendor/github.com/json-iterator/go/feature_reflect_native.go b/vendor/github.com/json-iterator/go/feature_reflect_native.go deleted file mode 100644 index b37dab3d8..000000000 --- a/vendor/github.com/json-iterator/go/feature_reflect_native.go +++ /dev/null @@ -1,672 +0,0 @@ -package jsoniter - -import ( - "encoding" - "encoding/base64" - "encoding/json" - "unsafe" -) - -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) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*string)(ptr)) == "" -} - -type intCodec struct { -} - -func (codec *intCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*int)(ptr)) = iter.ReadInt() -} - -func (codec *intCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt(*((*int)(ptr))) -} - -func (codec *intCodec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *intCodec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int)(ptr)) == 0 -} - -type uintptrCodec struct { -} - -func (codec *uintptrCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uintptr)(ptr)) = uintptr(iter.ReadUint64()) -} - -func (codec *uintptrCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint64(uint64(*((*uintptr)(ptr)))) -} - -func (codec *uintptrCodec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *uintptrCodec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uintptr)(ptr)) == 0 -} - -type int8Codec struct { -} - -func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*int8)(ptr)) = iter.ReadInt8() -} - -func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt8(*((*int8)(ptr))) -} - -func (codec *int8Codec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int8)(ptr)) == 0 -} - -type int16Codec struct { -} - -func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*int16)(ptr)) = iter.ReadInt16() -} - -func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt16(*((*int16)(ptr))) -} - -func (codec *int16Codec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int16)(ptr)) == 0 -} - -type int32Codec struct { -} - -func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*int32)(ptr)) = iter.ReadInt32() -} - -func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt32(*((*int32)(ptr))) -} - -func (codec *int32Codec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int32)(ptr)) == 0 -} - -type int64Codec struct { -} - -func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*int64)(ptr)) = iter.ReadInt64() -} - -func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt64(*((*int64)(ptr))) -} - -func (codec *int64Codec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int64)(ptr)) == 0 -} - -type uintCodec struct { -} - -func (codec *uintCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uint)(ptr)) = iter.ReadUint() -} - -func (codec *uintCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint(*((*uint)(ptr))) -} - -func (codec *uintCodec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *uintCodec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint)(ptr)) == 0 -} - -type uint8Codec struct { -} - -func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uint8)(ptr)) = iter.ReadUint8() -} - -func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint8(*((*uint8)(ptr))) -} - -func (codec *uint8Codec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint8)(ptr)) == 0 -} - -type uint16Codec struct { -} - -func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uint16)(ptr)) = iter.ReadUint16() -} - -func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint16(*((*uint16)(ptr))) -} - -func (codec *uint16Codec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint16)(ptr)) == 0 -} - -type uint32Codec struct { -} - -func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uint32)(ptr)) = iter.ReadUint32() -} - -func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint32(*((*uint32)(ptr))) -} - -func (codec *uint32Codec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint32)(ptr)) == 0 -} - -type uint64Codec struct { -} - -func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uint64)(ptr)) = iter.ReadUint64() -} - -func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint64(*((*uint64)(ptr))) -} - -func (codec *uint64Codec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint64)(ptr)) == 0 -} - -type float32Codec struct { -} - -func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*float32)(ptr)) = iter.ReadFloat32() -} - -func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat32(*((*float32)(ptr))) -} - -func (codec *float32Codec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*float32)(ptr)) == 0 -} - -type float64Codec struct { -} - -func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*float64)(ptr)) = iter.ReadFloat64() -} - -func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat64(*((*float64)(ptr))) -} - -func (codec *float64Codec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*float64)(ptr)) == 0 -} - -type boolCodec struct { -} - -func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*bool)(ptr)) = iter.ReadBool() -} - -func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteBool(*((*bool)(ptr))) -} - -func (codec *boolCodec) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, codec) -} - -func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool { - return !(*((*bool)(ptr))) -} - -type emptyInterfaceCodec struct { -} - -func (codec *emptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*interface{})(ptr)) = iter.Read() -} - -func (codec *emptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteVal(*((*interface{})(ptr))) -} - -func (codec *emptyInterfaceCodec) EncodeInterface(val interface{}, stream *Stream) { - stream.WriteVal(val) -} - -func (codec *emptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool { - return ptr == nil -} - -type nonEmptyInterfaceCodec struct { -} - -func (codec *nonEmptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - nonEmptyInterface := (*nonEmptyInterface)(ptr) - if nonEmptyInterface.itab == nil { - iter.ReportError("read non-empty interface", "do not know which concrete type to decode to") - return - } - var i interface{} - e := (*emptyInterface)(unsafe.Pointer(&i)) - e.typ = nonEmptyInterface.itab.typ - e.word = nonEmptyInterface.word - iter.ReadVal(&i) - nonEmptyInterface.word = e.word -} - -func (codec *nonEmptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - nonEmptyInterface := (*nonEmptyInterface)(ptr) - var i interface{} - e := (*emptyInterface)(unsafe.Pointer(&i)) - e.typ = nonEmptyInterface.itab.typ - e.word = nonEmptyInterface.word - stream.WriteVal(i) -} - -func (codec *nonEmptyInterfaceCodec) EncodeInterface(val interface{}, stream *Stream) { - stream.WriteVal(val) -} - -func (codec *nonEmptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool { - nonEmptyInterface := (*nonEmptyInterface)(ptr) - return nonEmptyInterface.word == nil -} - -type anyCodec struct { -} - -func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*Any)(ptr)) = iter.ReadAny() -} - -func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - (*((*Any)(ptr))).WriteTo(stream) -} - -func (codec *anyCodec) EncodeInterface(val interface{}, stream *Stream) { - (val.(Any)).WriteTo(stream) -} - -func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool { - return (*((*Any)(ptr))).Size() == 0 -} - -type jsonNumberCodec struct { -} - -func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) -} - -func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteRaw(string(*((*json.Number)(ptr)))) -} - -func (codec *jsonNumberCodec) EncodeInterface(val interface{}, stream *Stream) { - stream.WriteRaw(string(val.(json.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) { - *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) -} - -func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteRaw(string(*((*Number)(ptr)))) -} - -func (codec *jsoniterNumberCodec) EncodeInterface(val interface{}, stream *Stream) { - stream.WriteRaw(string(val.(Number))) -} - -func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*Number)(ptr))) == 0 -} - -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) EncodeInterface(val interface{}, stream *Stream) { - stream.WriteRaw(string(val.(json.RawMessage))) -} - -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) EncodeInterface(val interface{}, stream *Stream) { - stream.WriteRaw(string(val.(RawMessage))) -} - -func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*RawMessage)(ptr))) == 0 -} - -type base64Codec struct { - sliceDecoder ValDecoder -} - -func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.ReadNil() { - ptrSlice := (*sliceHeader)(ptr) - ptrSlice.Len = 0 - ptrSlice.Cap = 0 - ptrSlice.Data = nil - return - } - switch iter.WhatIsNext() { - case StringValue: - encoding := base64.StdEncoding - src := iter.SkipAndReturnBytes() - src = src[1 : len(src)-1] - decodedLen := encoding.DecodedLen(len(src)) - dst := make([]byte, decodedLen) - len, err := encoding.Decode(dst, src) - if err != nil { - iter.ReportError("decode base64", err.Error()) - } else { - dst = dst[:len] - dstSlice := (*sliceHeader)(unsafe.Pointer(&dst)) - ptrSlice := (*sliceHeader)(ptr) - ptrSlice.Data = dstSlice.Data - ptrSlice.Cap = dstSlice.Cap - ptrSlice.Len = dstSlice.Len - } - 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('"') - toGrow := encoding.EncodedLen(len(src)) - stream.ensure(toGrow) - encoding.Encode(stream.buf[stream.n:], src) - stream.n += toGrow - stream.writeByte('"') -} - -func (codec *base64Codec) EncodeInterface(val interface{}, stream *Stream) { - ptr := extractInterface(val).word - src := *((*[]byte)(ptr)) - if len(src) == 0 { - stream.WriteNil() - return - } - encoding := base64.StdEncoding - stream.writeByte('"') - toGrow := encoding.EncodedLen(len(src)) - stream.ensure(toGrow) - encoding.Encode(stream.buf[stream.n:], src) - stream.n += toGrow - stream.writeByte('"') -} - -func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*[]byte)(ptr))) == 0 -} - -type stringModeNumberDecoder struct { - elemDecoder ValDecoder -} - -func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - c := iter.nextToken() - if c != '"' { - iter.ReportError("stringModeNumberDecoder", `expect "`) - return - } - decoder.elemDecoder.Decode(ptr, iter) - if iter.Error != nil { - return - } - c = iter.readByte() - if c != '"' { - iter.ReportError("stringModeNumberDecoder", `expect "`) - return - } -} - -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 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) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -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) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.elemEncoder.IsEmpty(ptr) -} - -type marshalerEncoder struct { - templateInterface emptyInterface - checkIsEmpty checkIsEmpty -} - -func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - templateInterface := encoder.templateInterface - templateInterface.word = ptr - realInterface := (*interface{})(unsafe.Pointer(&templateInterface)) - marshaler := (*realInterface).(json.Marshaler) - bytes, err := marshaler.MarshalJSON() - if err != nil { - stream.Error = err - } else { - stream.Write(bytes) - } -} -func (encoder *marshalerEncoder) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.checkIsEmpty.IsEmpty(ptr) -} - -type textMarshalerEncoder struct { - templateInterface emptyInterface - checkIsEmpty checkIsEmpty -} - -func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - templateInterface := encoder.templateInterface - templateInterface.word = ptr - realInterface := (*interface{})(unsafe.Pointer(&templateInterface)) - marshaler := (*realInterface).(encoding.TextMarshaler) - bytes, err := marshaler.MarshalText() - if err != nil { - stream.Error = err - } else { - stream.WriteString(string(bytes)) - } -} - -func (encoder *textMarshalerEncoder) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.checkIsEmpty.IsEmpty(ptr) -} - -type unmarshalerDecoder struct { - templateInterface emptyInterface -} - -func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - templateInterface := decoder.templateInterface - templateInterface.word = ptr - realInterface := (*interface{})(unsafe.Pointer(&templateInterface)) - unmarshaler := (*realInterface).(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 { - templateInterface emptyInterface -} - -func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - templateInterface := decoder.templateInterface - templateInterface.word = ptr - realInterface := (*interface{})(unsafe.Pointer(&templateInterface)) - unmarshaler := (*realInterface).(encoding.TextUnmarshaler) - str := iter.ReadString() - err := unmarshaler.UnmarshalText([]byte(str)) - if err != nil { - iter.ReportError("textUnmarshalerDecoder", err.Error()) - } -} diff --git a/vendor/github.com/json-iterator/go/feature_reflect_slice.go b/vendor/github.com/json-iterator/go/feature_reflect_slice.go deleted file mode 100644 index 7377eec7b..000000000 --- a/vendor/github.com/json-iterator/go/feature_reflect_slice.go +++ /dev/null @@ -1,149 +0,0 @@ -package jsoniter - -import ( - "fmt" - "io" - "reflect" - "unsafe" -) - -func decoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { - decoder, err := decoderOfType(cfg, typ.Elem()) - if err != nil { - return nil, err - } - return &sliceDecoder{typ, typ.Elem(), decoder}, nil -} - -func encoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { - encoder, err := encoderOfType(cfg, typ.Elem()) - if err != nil { - return nil, err - } - if typ.Elem().Kind() == reflect.Map { - encoder = &optionalEncoder{encoder} - } - return &sliceEncoder{typ, typ.Elem(), encoder}, nil -} - -type sliceEncoder struct { - sliceType reflect.Type - elemType reflect.Type - elemEncoder ValEncoder -} - -func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - slice := (*sliceHeader)(ptr) - if slice.Data == nil { - stream.WriteNil() - return - } - if slice.Len == 0 { - stream.WriteEmptyArray() - return - } - stream.WriteArrayStart() - elemPtr := unsafe.Pointer(slice.Data) - encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream) - for i := 1; i < slice.Len; i++ { - stream.WriteMore() - elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size()) - encoder.elemEncoder.Encode(unsafe.Pointer(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) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - -func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool { - slice := (*sliceHeader)(ptr) - return slice.Len == 0 -} - -type sliceDecoder struct { - sliceType reflect.Type - elemType reflect.Type - elemDecoder ValDecoder -} - -// sliceHeader is a safe version of SliceHeader used within this package. -type sliceHeader struct { - Data unsafe.Pointer - Len int - Cap int -} - -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) { - slice := (*sliceHeader)(ptr) - if iter.ReadNil() { - slice.Len = 0 - slice.Cap = 0 - slice.Data = nil - return - } - reuseSlice(slice, decoder.sliceType, 4) - slice.Len = 0 - offset := uintptr(0) - iter.ReadArrayCB(func(iter *Iterator) bool { - growOne(slice, decoder.sliceType, decoder.elemType) - decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter) - offset += decoder.elemType.Size() - return true - }) -} - -// grow grows the slice s so that it can hold extra more values, allocating -// more capacity if needed. It also returns the old and new slice lengths. -func growOne(slice *sliceHeader, sliceType reflect.Type, elementType reflect.Type) { - newLen := slice.Len + 1 - if newLen <= slice.Cap { - slice.Len = newLen - return - } - newCap := slice.Cap - if newCap == 0 { - newCap = 1 - } else { - for newCap < newLen { - if slice.Len < 1024 { - newCap += newCap - } else { - newCap += newCap / 4 - } - } - } - newVal := reflect.MakeSlice(sliceType, newLen, newCap) - dst := unsafe.Pointer(newVal.Pointer()) - // copy old array into new array - originalBytesCount := uintptr(slice.Len) * elementType.Size() - srcPtr := (*[1 << 30]byte)(slice.Data) - dstPtr := (*[1 << 30]byte)(dst) - for i := uintptr(0); i < originalBytesCount; i++ { - dstPtr[i] = srcPtr[i] - } - slice.Data = dst - slice.Len = newLen - slice.Cap = newCap -} - -func reuseSlice(slice *sliceHeader, sliceType reflect.Type, expectedCap int) { - if expectedCap <= slice.Cap { - return - } - newVal := reflect.MakeSlice(sliceType, 0, expectedCap) - dst := unsafe.Pointer(newVal.Pointer()) - slice.Data = dst - slice.Cap = expectedCap -} diff --git a/vendor/github.com/json-iterator/go/feature_stream_int.go b/vendor/github.com/json-iterator/go/feature_stream_int.go deleted file mode 100644 index 7cfd522c1..000000000 --- a/vendor/github.com/json-iterator/go/feature_stream_int.go +++ /dev/null @@ -1,320 +0,0 @@ -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(buf []byte, v uint32, n int) int { - start := v >> 24 - if start == 0 { - buf[n] = byte(v >> 16) - n++ - buf[n] = byte(v >> 8) - n++ - } else if start == 1 { - buf[n] = byte(v >> 8) - n++ - } - buf[n] = byte(v) - n++ - return n -} - -func writeBuf(buf []byte, v uint32, n int) { - buf[n] = byte(v >> 16) - buf[n+1] = byte(v >> 8) - buf[n+2] = byte(v) -} - -// WriteUint8 write uint8 to stream -func (stream *Stream) WriteUint8(val uint8) { - stream.ensure(3) - stream.n = writeFirstBuf(stream.buf, digits[val], stream.n) -} - -// WriteInt8 write int8 to stream -func (stream *Stream) WriteInt8(nval int8) { - stream.ensure(4) - n := stream.n - var val uint8 - if nval < 0 { - val = uint8(-nval) - stream.buf[n] = '-' - n++ - } else { - val = uint8(nval) - } - stream.n = writeFirstBuf(stream.buf, digits[val], n) -} - -// WriteUint16 write uint16 to stream -func (stream *Stream) WriteUint16(val uint16) { - stream.ensure(5) - q1 := val / 1000 - if q1 == 0 { - stream.n = writeFirstBuf(stream.buf, digits[val], stream.n) - return - } - r1 := val - q1*1000 - n := writeFirstBuf(stream.buf, digits[q1], stream.n) - writeBuf(stream.buf, digits[r1], n) - stream.n = n + 3 - return -} - -// WriteInt16 write int16 to stream -func (stream *Stream) WriteInt16(nval int16) { - stream.ensure(6) - n := stream.n - var val uint16 - if nval < 0 { - val = uint16(-nval) - stream.buf[n] = '-' - n++ - } else { - val = uint16(nval) - } - q1 := val / 1000 - if q1 == 0 { - stream.n = writeFirstBuf(stream.buf, digits[val], n) - return - } - r1 := val - q1*1000 - n = writeFirstBuf(stream.buf, digits[q1], n) - writeBuf(stream.buf, digits[r1], n) - stream.n = n + 3 - return -} - -// WriteUint32 write uint32 to stream -func (stream *Stream) WriteUint32(val uint32) { - stream.ensure(10) - n := stream.n - q1 := val / 1000 - if q1 == 0 { - stream.n = writeFirstBuf(stream.buf, digits[val], n) - return - } - r1 := val - q1*1000 - q2 := q1 / 1000 - if q2 == 0 { - n := writeFirstBuf(stream.buf, digits[q1], n) - writeBuf(stream.buf, digits[r1], n) - stream.n = n + 3 - return - } - r2 := q1 - q2*1000 - q3 := q2 / 1000 - if q3 == 0 { - n = writeFirstBuf(stream.buf, digits[q2], n) - } else { - r3 := q2 - q3*1000 - stream.buf[n] = byte(q3 + '0') - n++ - writeBuf(stream.buf, digits[r3], n) - n += 3 - } - writeBuf(stream.buf, digits[r2], n) - writeBuf(stream.buf, digits[r1], n+3) - stream.n = n + 6 -} - -// WriteInt32 write int32 to stream -func (stream *Stream) WriteInt32(nval int32) { - stream.ensure(11) - n := stream.n - var val uint32 - if nval < 0 { - val = uint32(-nval) - stream.buf[n] = '-' - n++ - } else { - val = uint32(nval) - } - q1 := val / 1000 - if q1 == 0 { - stream.n = writeFirstBuf(stream.buf, digits[val], n) - return - } - r1 := val - q1*1000 - q2 := q1 / 1000 - if q2 == 0 { - n := writeFirstBuf(stream.buf, digits[q1], n) - writeBuf(stream.buf, digits[r1], n) - stream.n = n + 3 - return - } - r2 := q1 - q2*1000 - q3 := q2 / 1000 - if q3 == 0 { - n = writeFirstBuf(stream.buf, digits[q2], n) - } else { - r3 := q2 - q3*1000 - stream.buf[n] = byte(q3 + '0') - n++ - writeBuf(stream.buf, digits[r3], n) - n += 3 - } - writeBuf(stream.buf, digits[r2], n) - writeBuf(stream.buf, digits[r1], n+3) - stream.n = n + 6 -} - -// WriteUint64 write uint64 to stream -func (stream *Stream) WriteUint64(val uint64) { - stream.ensure(20) - n := stream.n - q1 := val / 1000 - if q1 == 0 { - stream.n = writeFirstBuf(stream.buf, digits[val], n) - return - } - r1 := val - q1*1000 - q2 := q1 / 1000 - if q2 == 0 { - n := writeFirstBuf(stream.buf, digits[q1], n) - writeBuf(stream.buf, digits[r1], n) - stream.n = n + 3 - return - } - r2 := q1 - q2*1000 - q3 := q2 / 1000 - if q3 == 0 { - n = writeFirstBuf(stream.buf, digits[q2], n) - writeBuf(stream.buf, digits[r2], n) - writeBuf(stream.buf, digits[r1], n+3) - stream.n = n + 6 - return - } - r3 := q2 - q3*1000 - q4 := q3 / 1000 - if q4 == 0 { - n = writeFirstBuf(stream.buf, digits[q3], n) - writeBuf(stream.buf, digits[r3], n) - writeBuf(stream.buf, digits[r2], n+3) - writeBuf(stream.buf, digits[r1], n+6) - stream.n = n + 9 - return - } - r4 := q3 - q4*1000 - q5 := q4 / 1000 - if q5 == 0 { - n = writeFirstBuf(stream.buf, digits[q4], n) - writeBuf(stream.buf, digits[r4], n) - writeBuf(stream.buf, digits[r3], n+3) - writeBuf(stream.buf, digits[r2], n+6) - writeBuf(stream.buf, digits[r1], n+9) - stream.n = n + 12 - return - } - r5 := q4 - q5*1000 - q6 := q5 / 1000 - if q6 == 0 { - n = writeFirstBuf(stream.buf, digits[q5], n) - } else { - n = writeFirstBuf(stream.buf, digits[q6], n) - r6 := q5 - q6*1000 - writeBuf(stream.buf, digits[r6], n) - n += 3 - } - writeBuf(stream.buf, digits[r5], n) - writeBuf(stream.buf, digits[r4], n+3) - writeBuf(stream.buf, digits[r3], n+6) - writeBuf(stream.buf, digits[r2], n+9) - writeBuf(stream.buf, digits[r1], n+12) - stream.n = n + 15 -} - -// WriteInt64 write int64 to stream -func (stream *Stream) WriteInt64(nval int64) { - stream.ensure(20) - n := stream.n - var val uint64 - if nval < 0 { - val = uint64(-nval) - stream.buf[n] = '-' - n++ - } else { - val = uint64(nval) - } - q1 := val / 1000 - if q1 == 0 { - stream.n = writeFirstBuf(stream.buf, digits[val], n) - return - } - r1 := val - q1*1000 - q2 := q1 / 1000 - if q2 == 0 { - n := writeFirstBuf(stream.buf, digits[q1], n) - writeBuf(stream.buf, digits[r1], n) - stream.n = n + 3 - return - } - r2 := q1 - q2*1000 - q3 := q2 / 1000 - if q3 == 0 { - n = writeFirstBuf(stream.buf, digits[q2], n) - writeBuf(stream.buf, digits[r2], n) - writeBuf(stream.buf, digits[r1], n+3) - stream.n = n + 6 - return - } - r3 := q2 - q3*1000 - q4 := q3 / 1000 - if q4 == 0 { - n = writeFirstBuf(stream.buf, digits[q3], n) - writeBuf(stream.buf, digits[r3], n) - writeBuf(stream.buf, digits[r2], n+3) - writeBuf(stream.buf, digits[r1], n+6) - stream.n = n + 9 - return - } - r4 := q3 - q4*1000 - q5 := q4 / 1000 - if q5 == 0 { - n = writeFirstBuf(stream.buf, digits[q4], n) - writeBuf(stream.buf, digits[r4], n) - writeBuf(stream.buf, digits[r3], n+3) - writeBuf(stream.buf, digits[r2], n+6) - writeBuf(stream.buf, digits[r1], n+9) - stream.n = n + 12 - return - } - r5 := q4 - q5*1000 - q6 := q5 / 1000 - if q6 == 0 { - n = writeFirstBuf(stream.buf, digits[q5], n) - } else { - stream.buf[n] = byte(q6 + '0') - n++ - r6 := q5 - q6*1000 - writeBuf(stream.buf, digits[r6], n) - n += 3 - } - writeBuf(stream.buf, digits[r5], n) - writeBuf(stream.buf, digits[r4], n+3) - writeBuf(stream.buf, digits[r3], n+6) - writeBuf(stream.buf, digits[r2], n+9) - writeBuf(stream.buf, digits[r1], n+12) - stream.n = n + 15 -} - -// 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)) -} diff --git a/vendor/github.com/json-iterator/go/feature_iter.go b/vendor/github.com/json-iterator/go/iter.go index 4357d69ba..95ae54fbf 100644 --- a/vendor/github.com/json-iterator/go/feature_iter.go +++ b/vendor/github.com/json-iterator/go/iter.go @@ -77,6 +77,7 @@ type Iterator struct { captureStartedAt int captured []byte Error error + Attachment interface{} // open for customized decoder } // NewIterator creates an empty Iterator instance @@ -167,7 +168,7 @@ func (iter *Iterator) isObjectEnd() bool { if c == '}' { return true } - iter.ReportError("isObjectEnd", "object ended prematurely") + iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c})) return true } @@ -200,8 +201,22 @@ func (iter *Iterator) ReportError(operation string, msg string) { if peekStart < 0 { peekStart = 0 } - iter.Error = fmt.Errorf("%s: %s, parsing %v ...%s... at %s", operation, msg, iter.head, - string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) + 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 @@ -210,7 +225,7 @@ func (iter *Iterator) CurrentBuffer() string { if peekStart < 0 { peekStart = 0 } - return fmt.Sprintf("parsing %v ...|%s|... at %s", iter.head, + 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])) } diff --git a/vendor/github.com/json-iterator/go/feature_iter_array.go b/vendor/github.com/json-iterator/go/iter_array.go index cbc3ec8d1..6188cb457 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_array.go +++ b/vendor/github.com/json-iterator/go/iter_array.go @@ -19,7 +19,7 @@ func (iter *Iterator) ReadArray() (ret bool) { case ',': return true default: - iter.ReportError("ReadArray", "expect [ or , or ] or n, but found: "+string([]byte{c})) + iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c})) return } } @@ -42,7 +42,7 @@ func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { c = iter.nextToken() } if c != ']' { - iter.ReportError("ReadArrayCB", "expect ] in the end") + iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) return false } return true @@ -53,6 +53,6 @@ func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { iter.skipThreeBytes('u', 'l', 'l') return true // null } - iter.ReportError("ReadArrayCB", "expect [ or n, but found: "+string([]byte{c})) + iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c})) return false } diff --git a/vendor/github.com/json-iterator/go/feature_iter_float.go b/vendor/github.com/json-iterator/go/iter_float.go index 86f459912..4f883c095 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_float.go +++ b/vendor/github.com/json-iterator/go/iter_float.go @@ -1,6 +1,7 @@ package jsoniter import ( + "encoding/json" "io" "math/big" "strconv" @@ -339,3 +340,8 @@ func validateFloat(str string) string { } return "" } + +// ReadNumber read json.Number +func (iter *Iterator) ReadNumber() (ret json.Number) { + return json.Number(iter.readNumberAsString()) +} diff --git a/vendor/github.com/json-iterator/go/feature_iter_int.go b/vendor/github.com/json-iterator/go/iter_int.go index 886879efd..214232035 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_int.go +++ b/vendor/github.com/json-iterator/go/iter_int.go @@ -22,11 +22,17 @@ func init() { // 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()) } @@ -115,6 +121,7 @@ func (iter *Iterator) ReadUint32() (ret uint32) { func (iter *Iterator) readUint32(c byte) (ret uint32) { ind := intDigits[c] if ind == 0 { + iter.assertInteger() return 0 // single zero } if ind == invalidCharForNumber { @@ -127,12 +134,14 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { 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 @@ -141,30 +150,35 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { 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++ @@ -172,6 +186,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { 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 } } @@ -180,6 +195,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { ind = intDigits[iter.buf[i]] if ind == invalidCharForNumber { iter.head = i + iter.assertInteger() return value } if value > uint32SafeToMultiply10 { @@ -194,6 +210,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { value = (value << 3) + (value << 1) + uint32(ind) } if !iter.loadMore() { + iter.assertInteger() return value } } @@ -226,6 +243,7 @@ func (iter *Iterator) ReadUint64() uint64 { func (iter *Iterator) readUint64(c byte) (ret uint64) { ind := intDigits[c] if ind == 0 { + iter.assertInteger() return 0 // single zero } if ind == invalidCharForNumber { @@ -233,11 +251,73 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) { 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 { @@ -252,7 +332,14 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) { 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") + } +} diff --git a/vendor/github.com/json-iterator/go/feature_iter_object.go b/vendor/github.com/json-iterator/go/iter_object.go index 3bdb5576e..1c5757671 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_object.go +++ b/vendor/github.com/json-iterator/go/iter_object.go @@ -2,8 +2,7 @@ package jsoniter import ( "fmt" - "unicode" - "unsafe" + "strings" ) // ReadObject read one field from object. @@ -19,15 +18,25 @@ func (iter *Iterator) ReadObject() (ret string) { c = iter.nextToken() if c == '"' { iter.unreadByte() - return string(iter.readObjectFieldAsBytes()) + 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 {`) + iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) return case ',': - return string(iter.readObjectFieldAsBytes()) + 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: @@ -36,62 +45,92 @@ func (iter *Iterator) ReadObject() (ret string) { } } -func (iter *Iterator) readFieldHash() int32 { +// CaseInsensitive +func (iter *Iterator) readFieldHash() int64 { hash := int64(0x811c9dc5) c := iter.nextToken() - if c == '"' { - for { - for i := iter.head; i < iter.tail; i++ { - // require ascii string and no escape - b := iter.buf[i] - if 'A' <= b && b <= 'Z' { - b += 'a' - 'A' - } - if b == '"' { - iter.head = i + 1 - c = iter.nextToken() - if c != ':' { - iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + 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' } - return int32(hash) + 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 } - hash ^= int64(b) - hash *= 0x1000193 + return hash } - if !iter.loadMore() { - iter.ReportError("readFieldHash", `incomplete field name`) - return 0 + 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 } } - iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) - return 0 } -func calcHash(str string) int32 { +func calcHash(str string, caseSensitive bool) int64 { + if !caseSensitive { + str = strings.ToLower(str) + } hash := int64(0x811c9dc5) - for _, b := range str { - hash ^= int64(unicode.ToLower(b)) + for _, b := range []byte(str) { + hash ^= int64(b) hash *= 0x1000193 } - return int32(hash) + 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.readObjectFieldAsBytes() - if !callback(iter, *(*string)(unsafe.Pointer(&field))) { + 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.readObjectFieldAsBytes() - if !callback(iter, *(*string)(unsafe.Pointer(&field))) { + 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() @@ -105,14 +144,14 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { if c == '}' { return true } - iter.ReportError("ReadObjectCB", `expect " after }`) + 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`) + iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) return false } @@ -125,7 +164,7 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { iter.unreadByte() field := iter.ReadString() if iter.nextToken() != ':' { - iter.ReportError("ReadMapCB", "expect : after object field") + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) return false } if !callback(iter, field) { @@ -135,7 +174,7 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { for c == ',' { field = iter.ReadString() if iter.nextToken() != ':' { - iter.ReportError("ReadMapCB", "expect : after object field") + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) return false } if !callback(iter, field) { @@ -152,14 +191,14 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { if c == '}' { return true } - iter.ReportError("ReadMapCB", `expect " after }`) + 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`) + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) return false } @@ -176,7 +215,7 @@ func (iter *Iterator) readObjectStart() bool { iter.skipThreeBytes('u', 'l', 'l') return false } - iter.ReportError("readObjectStart", "expect { or n") + iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) return false } @@ -192,7 +231,7 @@ func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { } } if iter.buf[iter.head] != ':' { - iter.ReportError("readObjectFieldAsBytes", "expect : after object field") + iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) return } iter.head++ diff --git a/vendor/github.com/json-iterator/go/feature_iter_skip.go b/vendor/github.com/json-iterator/go/iter_skip.go index b008d98c9..f58beb913 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_skip.go +++ b/vendor/github.com/json-iterator/go/iter_skip.go @@ -25,7 +25,7 @@ func (iter *Iterator) ReadBool() (ret bool) { iter.skipFourBytes('a', 'l', 's', 'e') return false } - iter.ReportError("ReadBool", "expect t or f") + iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c})) return } @@ -59,7 +59,9 @@ func (iter *Iterator) stopCapture() []byte { iter.captureStartedAt = -1 iter.captured = nil if len(captured) == 0 { - return remaining + copied := make([]byte, len(remaining)) + copy(copied, remaining) + return copied } captured = append(captured, remaining...) return captured diff --git a/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go index 047d58a4b..8fcdc3b69 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go +++ b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go @@ -1,4 +1,4 @@ -//+build jsoniter-sloppy +//+build jsoniter_sloppy package jsoniter diff --git a/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go b/vendor/github.com/json-iterator/go/iter_skip_strict.go index d26763825..f67bc2e83 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go +++ b/vendor/github.com/json-iterator/go/iter_skip_strict.go @@ -1,4 +1,4 @@ -//+build !jsoniter-sloppy +//+build !jsoniter_sloppy package jsoniter @@ -64,7 +64,7 @@ func (iter *Iterator) trySkipString() bool { } else if c == '\\' { return false } else if c < ' ' { - iter.ReportError("ReadString", + iter.ReportError("trySkipString", fmt.Sprintf(`invalid control character found: %d`, c)) return true // already failed } diff --git a/vendor/github.com/json-iterator/go/feature_iter_string.go b/vendor/github.com/json-iterator/go/iter_str.go index b76460046..adc487ea8 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_string.go +++ b/vendor/github.com/json-iterator/go/iter_str.go @@ -28,7 +28,7 @@ func (iter *Iterator) ReadString() (ret string) { iter.skipThreeBytes('u', 'l', 'l') return "" } - iter.ReportError("ReadString", `expects " or n`) + iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c})) return } @@ -47,7 +47,7 @@ func (iter *Iterator) readStringSlowPath() (ret string) { str = append(str, c) } } - iter.ReportError("ReadString", "unexpected end of input") + iter.ReportError("readStringSlowPath", "unexpected end of input") return } @@ -104,7 +104,7 @@ func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte { case 't': str = append(str, '\t') default: - iter.ReportError("ReadString", + iter.ReportError("readEscapedChar", `invalid escape char after \`) return nil } @@ -139,7 +139,7 @@ func (iter *Iterator) ReadStringAsSlice() (ret []byte) { } return copied } - iter.ReportError("ReadString", `expects " or n`) + iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c})) return } @@ -156,7 +156,7 @@ func (iter *Iterator) readU4() (ret rune) { } else if c >= 'A' && c <= 'F' { ret = ret*16 + rune(c-'A'+10) } else { - iter.ReportError("readU4", "expects 0~9 or a~f") + iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c})) return } } diff --git a/vendor/github.com/json-iterator/go/feature_pool.go b/vendor/github.com/json-iterator/go/pool.go index 73962bc6f..e2389b56c 100644 --- a/vendor/github.com/json-iterator/go/feature_pool.go +++ b/vendor/github.com/json-iterator/go/pool.go @@ -17,41 +17,26 @@ type StreamPool interface { } func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { - select { - case stream := <-cfg.streamPool: - stream.Reset(writer) - return stream - default: - return NewStream(cfg, writer, 512) - } + stream := cfg.streamPool.Get().(*Stream) + stream.Reset(writer) + return stream } func (cfg *frozenConfig) ReturnStream(stream *Stream) { + stream.out = nil stream.Error = nil - select { - case cfg.streamPool <- stream: - return - default: - return - } + stream.Attachment = nil + cfg.streamPool.Put(stream) } func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator { - select { - case iter := <-cfg.iteratorPool: - iter.ResetBytes(data) - return iter - default: - return ParseBytes(cfg, data) - } + iter := cfg.iteratorPool.Get().(*Iterator) + iter.ResetBytes(data) + return iter } func (cfg *frozenConfig) ReturnIterator(iter *Iterator) { iter.Error = nil - select { - case cfg.iteratorPool <- iter: - return - default: - return - } + iter.Attachment = nil + cfg.iteratorPool.Put(iter) } diff --git a/vendor/github.com/json-iterator/go/reflect.go b/vendor/github.com/json-iterator/go/reflect.go new file mode 100644 index 000000000..4459e203f --- /dev/null +++ b/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) +} diff --git a/vendor/github.com/json-iterator/go/reflect_array.go b/vendor/github.com/json-iterator/go/reflect_array.go new file mode 100644 index 000000000..13a0b7b08 --- /dev/null +++ b/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 + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_dynamic.go b/vendor/github.com/json-iterator/go/reflect_dynamic.go new file mode 100644 index 000000000..8b6bc8b43 --- /dev/null +++ b/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) +} diff --git a/vendor/github.com/json-iterator/go/feature_reflect_extension.go b/vendor/github.com/json-iterator/go/reflect_extension.go index 3dd38299d..04f68756b 100644 --- a/vendor/github.com/json-iterator/go/feature_reflect_extension.go +++ b/vendor/github.com/json-iterator/go/reflect_extension.go @@ -2,6 +2,7 @@ package jsoniter import ( "fmt" + "github.com/modern-go/reflect2" "reflect" "sort" "strings" @@ -17,17 +18,15 @@ var extensions = []Extension{} // StructDescriptor describe how should we encode/decode the struct type StructDescriptor struct { - onePtrEmbedded bool - onePtrOptimization bool - Type reflect.Type - Fields []*Binding + 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 { + if binding.Field.Name() == fieldName { return binding } } @@ -37,7 +36,7 @@ func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding { // Binding describe how should we encode/decode the struct field type Binding struct { levels []int - Field *reflect.StructField + Field reflect2.StructField FromNames []string ToNames []string Encoder ValEncoder @@ -48,10 +47,12 @@ type Binding struct { // Can also rename fields by UpdateStructDescriptor. type Extension interface { UpdateStructDescriptor(structDescriptor *StructDescriptor) - CreateDecoder(typ reflect.Type) ValDecoder - CreateEncoder(typ reflect.Type) ValEncoder - DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder - DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder + 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 @@ -62,23 +63,105 @@ type DummyExtension struct { 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 *DummyExtension) CreateDecoder(typ reflect.Type) ValDecoder { +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 *DummyExtension) CreateEncoder(typ reflect.Type) ValEncoder { +func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { return nil } // DecorateDecoder No-op -func (extension *DummyExtension) DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder { +func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { return decoder } // DecorateEncoder No-op -func (extension *DummyExtension) DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder { +func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { return encoder } @@ -99,10 +182,6 @@ func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { encoder.fun(ptr, stream) } -func (encoder *funcEncoder) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { if encoder.isEmptyFunc == nil { return false @@ -161,132 +240,151 @@ func RegisterExtension(extension Extension) { extensions = append(extensions, extension) } -func getTypeDecoderFromExtension(typ reflect.Type) ValDecoder { - decoder := _getTypeDecoderFromExtension(typ) +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(typ reflect.Type) ValDecoder { +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] + decoder = typeDecoders[typeName] if decoder != nil { return decoder } if typ.Kind() == reflect.Ptr { - decoder := typeDecoders[typ.Elem().String()] + ptrType := typ.(*reflect2.UnsafePtrType) + decoder := typeDecoders[ptrType.Elem().String()] if decoder != nil { - return &optionalDecoder{typ.Elem(), decoder} + return &OptionalDecoder{ptrType.Elem(), decoder} } } return nil } -func getTypeEncoderFromExtension(typ reflect.Type) ValEncoder { - encoder := _getTypeEncoderFromExtension(typ) +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(typ reflect.Type) ValEncoder { +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] + encoder = typeEncoders[typeName] if encoder != nil { return encoder } if typ.Kind() == reflect.Ptr { - encoder := typeEncoders[typ.Elem().String()] + typePtr := typ.(*reflect2.UnsafePtrType) + encoder := typeEncoders[typePtr.Elem().String()] if encoder != nil { - return &optionalEncoder{encoder} + return &OptionalEncoder{encoder} } } return nil } -func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, error) { +func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor { + structType := typ.(*reflect2.UnsafeStructType) embeddedBindings := []*Binding{} bindings := []*Binding{} - for i := 0; i < typ.NumField(); i++ { - field := typ.Field(i) - tag := field.Tag.Get(cfg.getTagKey()) + 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, err := describeStruct(cfg, field.Type) - if err != nil { - return nil, err - } + 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} + 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 && field.Type.Elem().Kind() == reflect.Struct { - structDescriptor, err := describeStruct(cfg, field.Type.Elem()) - if err != nil { - return nil, err + } 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 } - for _, binding := range structDescriptor.Fields { - binding.levels = append([]int{i}, binding.levels...) - omitempty := binding.Encoder.(*structFieldEncoder).omitempty - binding.Encoder = &optionalEncoder{binding.Encoder} - binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty} - binding.Decoder = &deferenceDecoder{field.Type.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) + fieldNames := calcFieldNames(field.Name(), tagParts[0], tag) + fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name()) decoder := fieldDecoders[fieldCacheKey] if decoder == nil { - var err error - decoder, err = decoderOfType(cfg, field.Type) - if err != nil { - return nil, err - } + decoder = decoderOfType(ctx.append(field.Name()), field.Type()) } encoder := fieldEncoders[fieldCacheKey] if encoder == nil { - var err error - encoder, err = encoderOfType(cfg, field.Type) - if err != nil { - return nil, err - } - // map is stored as pointer in the struct - if field.Type.Kind() == reflect.Map { - encoder = &optionalEncoder{encoder} - } + encoder = encoderOfType(ctx.append(field.Name()), field.Type()) } binding := &Binding{ - Field: &field, + Field: field, FromNames: fieldNames, ToNames: fieldNames, Decoder: decoder, @@ -295,35 +393,22 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err binding.levels = []int{i} bindings = append(bindings, binding) } - return createStructDescriptor(cfg, typ, bindings, embeddedBindings), nil -} -func createStructDescriptor(cfg *frozenConfig, typ reflect.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { - onePtrEmbedded := false - onePtrOptimization := false - if typ.NumField() == 1 { - firstField := typ.Field(0) - switch firstField.Type.Kind() { - case reflect.Ptr: - if firstField.Anonymous && firstField.Type.Elem().Kind() == reflect.Struct { - onePtrEmbedded = true - } - fallthrough - case reflect.Map: - onePtrOptimization = true - case reflect.Struct: - onePtrOptimization = isStructOnePtr(firstField.Type) - } - } + return createStructDescriptor(ctx, typ, bindings, embeddedBindings) +} +func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { structDescriptor := &StructDescriptor{ - onePtrEmbedded: onePtrEmbedded, - onePtrOptimization: onePtrOptimization, - Type: typ, - Fields: bindings, + Type: typ, + Fields: bindings, } for _, extension := range extensions { extension.UpdateStructDescriptor(structDescriptor) } - processTags(structDescriptor, cfg) + 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) @@ -331,21 +416,6 @@ func createStructDescriptor(cfg *frozenConfig, typ reflect.Type, bindings []*Bin return structDescriptor } -func isStructOnePtr(typ reflect.Type) bool { - if typ.NumField() == 1 { - firstField := typ.Field(0) - switch firstField.Type.Kind() { - case reflect.Ptr: - return true - case reflect.Map: - return true - case reflect.Struct: - return isStructOnePtr(firstField.Type) - } - } - return false -} - type sortableBindings []*Binding func (bindings sortableBindings) Len() int { @@ -373,12 +443,12 @@ func (bindings sortableBindings) Swap(i, j int) { func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) { for _, binding := range structDescriptor.Fields { shouldOmitEmpty := false - tagParts := strings.Split(binding.Field.Tag.Get(cfg.getTagKey()), ",") + 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 { + if binding.Field.Type().Kind() == reflect.String { binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg} binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg} } else { diff --git a/vendor/github.com/json-iterator/go/reflect_json_number.go b/vendor/github.com/json-iterator/go/reflect_json_number.go new file mode 100644 index 000000000..98d45c1ec --- /dev/null +++ b/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 +} diff --git a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go new file mode 100644 index 000000000..f2619936c --- /dev/null +++ b/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 +} diff --git a/vendor/github.com/json-iterator/go/reflect_map.go b/vendor/github.com/json-iterator/go/reflect_map.go new file mode 100644 index 000000000..7f66a88b0 --- /dev/null +++ b/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 } diff --git a/vendor/github.com/json-iterator/go/reflect_marshaler.go b/vendor/github.com/json-iterator/go/reflect_marshaler.go new file mode 100644 index 000000000..58ac959ad --- /dev/null +++ b/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()) + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_native.go b/vendor/github.com/json-iterator/go/reflect_native.go new file mode 100644 index 000000000..9042eb0cb --- /dev/null +++ b/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 +} diff --git a/vendor/github.com/json-iterator/go/reflect_optional.go b/vendor/github.com/json-iterator/go/reflect_optional.go new file mode 100644 index 000000000..43ec71d6d --- /dev/null +++ b/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) +} diff --git a/vendor/github.com/json-iterator/go/reflect_slice.go b/vendor/github.com/json-iterator/go/reflect_slice.go new file mode 100644 index 000000000..9441d79df --- /dev/null +++ b/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 + } +} diff --git a/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go index b3417fd73..355d2d116 100644 --- a/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go +++ b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go @@ -3,38 +3,78 @@ package jsoniter import ( "fmt" "io" - "reflect" "strings" "unsafe" + + "github.com/modern-go/reflect2" ) -func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (ValDecoder, error) { - knownHash := map[int32]struct{}{ +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}, nil + return &skipObjectDecoder{typ} case 1: for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) + fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} - return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}, nil + return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder} } case 2: - var fieldHash1 int32 - var fieldHash2 int32 + var fieldHash1 int64 + var fieldHash2 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) + fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldHash1 == 0 { @@ -45,19 +85,19 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder fieldDecoder2 = fieldDecoder } } - return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}, nil + return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2} case 3: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 + 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) + fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { @@ -72,21 +112,23 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &threeFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3} case 4: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 + 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) + fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { @@ -104,24 +146,26 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &fourFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4}, nil + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4} case 5: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 + 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) + fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { @@ -142,15 +186,18 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &fiveFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5} case 6: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 - var fieldName6 int32 + 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 @@ -158,10 +205,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder var fieldDecoder5 *structFieldDecoder var fieldDecoder6 *structFieldDecoder for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) + fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { @@ -185,16 +232,20 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &sixFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6} case 7: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 - var fieldName6 int32 - var fieldName7 int32 + 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 @@ -203,10 +254,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder var fieldDecoder6 *structFieldDecoder var fieldDecoder7 *structFieldDecoder for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) + fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { @@ -233,18 +284,22 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &sevenFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7}, nil + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7} case 8: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 - var fieldName6 int32 - var fieldName7 int32 - var fieldName8 int32 + 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 @@ -254,10 +309,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder var fieldDecoder7 *structFieldDecoder var fieldDecoder8 *structFieldDecoder for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) + fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { @@ -287,19 +342,24 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &eightFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8} case 9: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 - var fieldName6 int32 - var fieldName7 int32 - var fieldName8 int32 - var fieldName9 int32 + 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 @@ -310,10 +370,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder var fieldDecoder8 *structFieldDecoder var fieldDecoder9 *structFieldDecoder for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) + fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { @@ -346,20 +406,26 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &nineFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8, + fieldName9, fieldDecoder9} case 10: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 - var fieldName6 int32 - var fieldName7 int32 - var fieldName8 int32 - var fieldName9 int32 - var fieldName10 int32 + 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 @@ -371,10 +437,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder var fieldDecoder9 *structFieldDecoder var fieldDecoder10 *structFieldDecoder for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) + fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { @@ -410,48 +476,80 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &tenFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9, - fieldName10, fieldDecoder10}, nil + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8, + fieldName9, fieldDecoder9, + fieldName10, fieldDecoder10} } - return &generalStructDecoder{typ, fields}, nil + return &generalStructDecoder{typ, fields, false} } type generalStructDecoder struct { - typ reflect.Type - fields map[string]*structFieldDecoder + typ reflect2.Type + fields map[string]*structFieldDecoder + disallowUnknownFields bool } func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } - fieldBytes := iter.readObjectFieldAsBytes() - field := *(*string)(unsafe.Pointer(&fieldBytes)) - fieldDecoder := decoder.fields[strings.ToLower(field)] - if fieldDecoder == nil { - iter.Skip() - } else { - fieldDecoder.Decode(ptr, iter) + var c byte + for c = ','; c == ','; c = iter.nextToken() { + decoder.decodeOneField(ptr, iter) } - for iter.nextToken() == ',' { - fieldBytes = iter.readObjectFieldAsBytes() + 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[strings.ToLower(field)] - if fieldDecoder == nil { - iter.Skip() - } else { - fieldDecoder.Decode(ptr, iter) + 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 iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + 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 reflect.Type + typ reflect2.Type } func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { @@ -464,8 +562,8 @@ func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { } type oneFieldStructDecoder struct { - typ reflect.Type - fieldHash int32 + typ reflect2.Type + fieldHash int64 fieldDecoder *structFieldDecoder } @@ -484,15 +582,15 @@ func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } type twoFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 + typ reflect2.Type + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder } @@ -514,17 +612,17 @@ func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } type threeFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 + typ reflect2.Type + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder } @@ -548,19 +646,19 @@ func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } type fourFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 + typ reflect2.Type + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder } @@ -586,21 +684,21 @@ func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } type fiveFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 + typ reflect2.Type + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder } @@ -628,23 +726,23 @@ func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } type sixFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 + typ reflect2.Type + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder - fieldHash6 int32 + fieldHash6 int64 fieldDecoder6 *structFieldDecoder } @@ -674,25 +772,25 @@ func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } type sevenFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 + typ reflect2.Type + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder - fieldHash6 int32 + fieldHash6 int64 fieldDecoder6 *structFieldDecoder - fieldHash7 int32 + fieldHash7 int64 fieldDecoder7 *structFieldDecoder } @@ -724,27 +822,27 @@ func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } type eightFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 + typ reflect2.Type + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder - fieldHash6 int32 + fieldHash6 int64 fieldDecoder6 *structFieldDecoder - fieldHash7 int32 + fieldHash7 int64 fieldDecoder7 *structFieldDecoder - fieldHash8 int32 + fieldHash8 int64 fieldDecoder8 *structFieldDecoder } @@ -778,29 +876,29 @@ func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } type nineFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 + typ reflect2.Type + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder - fieldHash6 int32 + fieldHash6 int64 fieldDecoder6 *structFieldDecoder - fieldHash7 int32 + fieldHash7 int64 fieldDecoder7 *structFieldDecoder - fieldHash8 int32 + fieldHash8 int64 fieldDecoder8 *structFieldDecoder - fieldHash9 int32 + fieldHash9 int64 fieldDecoder9 *structFieldDecoder } @@ -836,31 +934,31 @@ func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } type tenFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 + typ reflect2.Type + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder - fieldHash6 int32 + fieldHash6 int64 fieldDecoder6 *structFieldDecoder - fieldHash7 int32 + fieldHash7 int64 fieldDecoder7 *structFieldDecoder - fieldHash8 int32 + fieldHash8 int64 fieldDecoder8 *structFieldDecoder - fieldHash9 int32 + fieldHash9 int64 fieldDecoder9 *structFieldDecoder - fieldHash10 int32 + fieldHash10 int64 fieldDecoder10 *structFieldDecoder } @@ -898,19 +996,53 @@ func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } type structFieldDecoder struct { - field *reflect.StructField + field reflect2.StructField fieldDecoder ValDecoder } func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - fieldPtr := unsafe.Pointer(uintptr(ptr) + decoder.field.Offset) + 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()) + 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 } } diff --git a/vendor/github.com/json-iterator/go/feature_reflect_object.go b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go index 59b1235c0..d0759cf64 100644 --- a/vendor/github.com/json-iterator/go/feature_reflect_object.go +++ b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go @@ -2,23 +2,20 @@ package jsoniter import ( "fmt" + "github.com/modern-go/reflect2" "io" "reflect" - "strings" "unsafe" ) -func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { +func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder { type bindingTo struct { binding *Binding toName string ignored bool } orderedBindings := []*bindingTo{} - structDescriptor, err := describeStruct(cfg, typ) - if err != nil { - return nil, err - } + structDescriptor := describeStruct(ctx, typ) for _, binding := range structDescriptor.Fields { for _, toName := range binding.ToNames { new := &bindingTo{ @@ -29,13 +26,13 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { if old.toName != toName { continue } - old.ignored, new.ignored = resolveConflictBinding(cfg, old.binding, new.binding) + old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding) } orderedBindings = append(orderedBindings, new) } } if len(orderedBindings) == 0 { - return &emptyStructEncoder{}, nil + return &emptyStructEncoder{} } finalOrderedFields := []structFieldTo{} for _, bindingTo := range orderedBindings { @@ -46,12 +43,36 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { }) } } - return &structEncoder{structDescriptor.onePtrEmbedded, structDescriptor.onePtrOptimization, finalOrderedFields}, nil + 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()) != "" + 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) { @@ -78,62 +99,41 @@ func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ig } } -func decoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { - bindings := map[string]*Binding{} - structDescriptor, err := describeStruct(cfg, typ) - if err != nil { - return nil, err - } - for _, binding := range structDescriptor.Fields { - for _, fromName := range binding.FromNames { - old := bindings[fromName] - if old == nil { - bindings[fromName] = binding - continue - } - ignoreOld, ignoreNew := resolveConflictBinding(cfg, old, binding) - if ignoreOld { - delete(bindings, fromName) - } - if !ignoreNew { - bindings[fromName] = binding - } - } - } - fields := map[string]*structFieldDecoder{} - for k, binding := range bindings { - fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder) - } - return createStructDecoder(typ, fields) -} - type structFieldEncoder struct { - field *reflect.StructField + field reflect2.StructField fieldEncoder ValEncoder omitempty bool } func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset) + 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()) + stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error()) } } -func (encoder *structFieldEncoder) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool { - fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset) + 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 { - onePtrEmbedded bool - onePtrOptimization bool - fields []structFieldTo + typ reflect2.Type + fields []structFieldTo } type structFieldTo struct { @@ -148,6 +148,9 @@ func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { continue } + if field.encoder.IsEmbeddedPtrNil(ptr) { + continue + } if isNotFirst { stream.WriteMore() } @@ -156,23 +159,8 @@ func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { isNotFirst = true } stream.WriteObjectEnd() -} - -func (encoder *structEncoder) EncodeInterface(val interface{}, stream *Stream) { - e := (*emptyInterface)(unsafe.Pointer(&val)) - if encoder.onePtrOptimization { - if e.word == nil && encoder.onePtrEmbedded { - stream.WriteObjectStart() - stream.WriteObjectEnd() - return - } - ptr := uintptr(e.word) - e.word = unsafe.Pointer(&ptr) - } - if reflect.TypeOf(val).Kind() == reflect.Ptr { - encoder.Encode(unsafe.Pointer(&e.word), stream) - } else { - encoder.Encode(e.word, stream) + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error()) } } @@ -187,10 +175,36 @@ func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { stream.WriteEmptyObject() } -func (encoder *emptyStructEncoder) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) -} - 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) +} diff --git a/vendor/github.com/json-iterator/go/feature_stream.go b/vendor/github.com/json-iterator/go/stream.go index 9c8470a03..17662fded 100644 --- a/vendor/github.com/json-iterator/go/feature_stream.go +++ b/vendor/github.com/json-iterator/go/stream.go @@ -4,15 +4,15 @@ import ( "io" ) -// Stream is a io.Writer like object, with JSON specific write functions. +// 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 - n int - Error error - indention int + cfg *frozenConfig + out io.Writer + buf []byte + Error error + indention int + Attachment interface{} // open for customized encoder } // NewStream create new stream instance. @@ -23,8 +23,7 @@ func NewStream(cfg API, out io.Writer, bufSize int) *Stream { return &Stream{ cfg: cfg.(*frozenConfig), out: out, - buf: make([]byte, bufSize), - n: 0, + buf: make([]byte, 0, bufSize), Error: nil, indention: 0, } @@ -38,22 +37,27 @@ func (stream *Stream) Pool() StreamPool { // Reset reuse this stream instance by assign a new writer func (stream *Stream) Reset(out io.Writer) { stream.out = out - stream.n = 0 + stream.buf = stream.buf[:0] } // Available returns how many bytes are unused in the buffer. func (stream *Stream) Available() int { - return len(stream.buf) - stream.n + 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 stream.n + return len(stream.buf) } // Buffer if writer is nil, use this method to take the result func (stream *Stream) Buffer() []byte { - return stream.buf[:stream.n] + 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. @@ -61,97 +65,34 @@ func (stream *Stream) Buffer() []byte { // 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) { - for len(p) > stream.Available() && stream.Error == nil { - if stream.out == nil { - stream.growAtLeast(len(p)) - } else { - var n int - if stream.Buffered() == 0 { - // Large write, empty buffer. - // Write directly from p to avoid copy. - n, stream.Error = stream.out.Write(p) - } else { - n = copy(stream.buf[stream.n:], p) - stream.n += n - stream.Flush() - } - nn += n - p = p[n:] - } - } - if stream.Error != nil { - return nn, stream.Error + stream.buf = append(stream.buf, p...) + if stream.out != nil { + nn, err = stream.out.Write(stream.buf) + stream.buf = stream.buf[nn:] + return } - n := copy(stream.buf[stream.n:], p) - stream.n += n - nn += n - return nn, nil + return len(p), nil } // WriteByte writes a single byte. func (stream *Stream) writeByte(c byte) { - if stream.Error != nil { - return - } - if stream.Available() < 1 { - stream.growAtLeast(1) - } - stream.buf[stream.n] = c - stream.n++ + stream.buf = append(stream.buf, c) } func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) { - if stream.Error != nil { - return - } - if stream.Available() < 2 { - stream.growAtLeast(2) - } - stream.buf[stream.n] = c1 - stream.buf[stream.n+1] = c2 - stream.n += 2 + stream.buf = append(stream.buf, c1, c2) } func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) { - if stream.Error != nil { - return - } - if stream.Available() < 3 { - stream.growAtLeast(3) - } - stream.buf[stream.n] = c1 - stream.buf[stream.n+1] = c2 - stream.buf[stream.n+2] = c3 - stream.n += 3 + stream.buf = append(stream.buf, c1, c2, c3) } func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) { - if stream.Error != nil { - return - } - if stream.Available() < 4 { - stream.growAtLeast(4) - } - stream.buf[stream.n] = c1 - stream.buf[stream.n+1] = c2 - stream.buf[stream.n+2] = c3 - stream.buf[stream.n+3] = c4 - stream.n += 4 + stream.buf = append(stream.buf, c1, c2, c3, c4) } func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) { - if stream.Error != nil { - return - } - if stream.Available() < 5 { - stream.growAtLeast(5) - } - stream.buf[stream.n] = c1 - stream.buf[stream.n+1] = c2 - stream.buf[stream.n+2] = c3 - stream.buf[stream.n+3] = c4 - stream.buf[stream.n+4] = c5 - stream.n += 5 + stream.buf = append(stream.buf, c1, c2, c3, c4, c5) } // Flush writes any buffered data to the underlying io.Writer. @@ -162,53 +103,20 @@ func (stream *Stream) Flush() error { if stream.Error != nil { return stream.Error } - if stream.n == 0 { - return nil - } - n, err := stream.out.Write(stream.buf[0:stream.n]) - if n < stream.n && err == nil { - err = io.ErrShortWrite - } + n, err := stream.out.Write(stream.buf) if err != nil { - if n > 0 && n < stream.n { - copy(stream.buf[0:stream.n-n], stream.buf[n:stream.n]) + if stream.Error == nil { + stream.Error = err } - stream.n -= n - stream.Error = err return err } - stream.n = 0 + stream.buf = stream.buf[n:] return nil } -func (stream *Stream) ensure(minimal int) { - available := stream.Available() - if available < minimal { - stream.growAtLeast(minimal) - } -} - -func (stream *Stream) growAtLeast(minimal int) { - if stream.out != nil { - stream.Flush() - } - toGrow := len(stream.buf) - if toGrow < minimal { - toGrow = minimal - } - newBuf := make([]byte, len(stream.buf)+toGrow) - copy(newBuf, stream.Buffer()) - stream.buf = newBuf -} - // WriteRaw write string out without quotes, just like []byte func (stream *Stream) WriteRaw(s string) { - stream.ensure(len(s)) - if stream.Error != nil { - return - } - n := copy(stream.buf[stream.n:], s) - stream.n += n + stream.buf = append(stream.buf, s...) } // WriteNil write null to stream @@ -269,6 +177,7 @@ func (stream *Stream) WriteEmptyObject() { func (stream *Stream) WriteMore() { stream.writeByte(',') stream.writeIndention(0) + stream.Flush() } // WriteArrayStart write [ with possible indention @@ -280,8 +189,7 @@ func (stream *Stream) WriteArrayStart() { // WriteEmptyArray write [] func (stream *Stream) WriteEmptyArray() { - stream.writeByte('[') - stream.writeByte(']') + stream.writeTwoBytes('[', ']') } // WriteArrayEnd write ] with possible indention @@ -297,9 +205,7 @@ func (stream *Stream) writeIndention(delta int) { } stream.writeByte('\n') toWrite := stream.indention - delta - stream.ensure(toWrite) - for i := 0; i < toWrite && stream.n < len(stream.buf); i++ { - stream.buf[stream.n] = ' ' - stream.n++ + for i := 0; i < toWrite; i++ { + stream.buf = append(stream.buf, ' ') } } diff --git a/vendor/github.com/json-iterator/go/feature_stream_float.go b/vendor/github.com/json-iterator/go/stream_float.go index 9a404e11d..f318d2c59 100644 --- a/vendor/github.com/json-iterator/go/feature_stream_float.go +++ b/vendor/github.com/json-iterator/go/stream_float.go @@ -21,7 +21,7 @@ func (stream *Stream) WriteFloat32(val float32) { fmt = 'e' } } - stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 32)) + 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 @@ -43,13 +43,12 @@ func (stream *Stream) WriteFloat32Lossy(val float32) { return } stream.writeByte('.') - stream.ensure(10) for p := precision - 1; p > 0 && fval < pow10[p]; p-- { stream.writeByte('0') } stream.WriteUint64(fval) - for stream.buf[stream.n-1] == '0' { - stream.n-- + for stream.buf[len(stream.buf)-1] == '0' { + stream.buf = stream.buf[:len(stream.buf)-1] } } @@ -63,7 +62,7 @@ func (stream *Stream) WriteFloat64(val float64) { fmt = 'e' } } - stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 64)) + 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 @@ -85,12 +84,11 @@ func (stream *Stream) WriteFloat64Lossy(val float64) { return } stream.writeByte('.') - stream.ensure(10) for p := precision - 1; p > 0 && fval < pow10[p]; p-- { stream.writeByte('0') } stream.WriteUint64(fval) - for stream.buf[stream.n-1] == '0' { - stream.n-- + for stream.buf[len(stream.buf)-1] == '0' { + stream.buf = stream.buf[:len(stream.buf)-1] } } diff --git a/vendor/github.com/json-iterator/go/stream_int.go b/vendor/github.com/json-iterator/go/stream_int.go new file mode 100644 index 000000000..d1059ee4c --- /dev/null +++ b/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)) +} diff --git a/vendor/github.com/json-iterator/go/feature_stream_string.go b/vendor/github.com/json-iterator/go/stream_str.go index 334282f05..54c2ba0b3 100644 --- a/vendor/github.com/json-iterator/go/feature_stream_string.go +++ b/vendor/github.com/json-iterator/go/stream_str.go @@ -219,34 +219,22 @@ var hex = "0123456789abcdef" // WriteStringWithHTMLEscaped write string to stream with html special characters escaped func (stream *Stream) WriteStringWithHTMLEscaped(s string) { - stream.ensure(32) valLen := len(s) - toWriteLen := valLen - bufLengthMinusTwo := len(stream.buf) - 2 // make room for the quotes - if stream.n+toWriteLen > bufLengthMinusTwo { - toWriteLen = bufLengthMinusTwo - stream.n - } - n := stream.n - stream.buf[n] = '"' - n++ + stream.buf = append(stream.buf, '"') // write string, the fast path, without utf8 and escape support i := 0 - for ; i < toWriteLen; i++ { + for ; i < valLen; i++ { c := s[i] if c < utf8.RuneSelf && htmlSafeSet[c] { - stream.buf[n] = c - n++ + stream.buf = append(stream.buf, c) } else { break } } if i == valLen { - stream.buf[n] = '"' - n++ - stream.n = n + stream.buf = append(stream.buf, '"') return } - stream.n = n writeStringSlowPathWithHTMLEscaped(stream, i, s, valLen) } @@ -321,34 +309,22 @@ func writeStringSlowPathWithHTMLEscaped(stream *Stream, i int, s string, valLen // WriteString write string to stream without html escape func (stream *Stream) WriteString(s string) { - stream.ensure(32) valLen := len(s) - toWriteLen := valLen - bufLengthMinusTwo := len(stream.buf) - 2 // make room for the quotes - if stream.n+toWriteLen > bufLengthMinusTwo { - toWriteLen = bufLengthMinusTwo - stream.n - } - n := stream.n - stream.buf[n] = '"' - n++ + stream.buf = append(stream.buf, '"') // write string, the fast path, without utf8 and escape support i := 0 - for ; i < toWriteLen; i++ { + for ; i < valLen; i++ { c := s[i] if c > 31 && c != '"' && c != '\\' { - stream.buf[n] = c - n++ + stream.buf = append(stream.buf, c) } else { break } } if i == valLen { - stream.buf[n] = '"' - n++ - stream.n = n + stream.buf = append(stream.buf, '"') return } - stream.n = n writeStringSlowPath(stream, i, s, valLen) } |