pax_global_header00006660000000000000000000000064142064446570014526gustar00rootroot0000000000000052 comment=2f7b9318e214703862ecf3d93c1b5494c3adba06 golang-github-json-iterator-go-1.1.12/000077500000000000000000000000001420644465700175405ustar00rootroot00000000000000golang-github-json-iterator-go-1.1.12/.codecov.yml000066400000000000000000000000411420644465700217560ustar00rootroot00000000000000ignore: - "output_tests/.*" golang-github-json-iterator-go-1.1.12/.gitignore000066400000000000000000000000521420644465700215250ustar00rootroot00000000000000/vendor /bug_test.go /coverage.txt /.idea golang-github-json-iterator-go-1.1.12/.travis.yml000066400000000000000000000002371420644465700216530ustar00rootroot00000000000000language: go go: - 1.8.x - 1.x before_install: - go get -t -v ./... script: - ./test.sh after_success: - bash <(curl -s https://codecov.io/bash) golang-github-json-iterator-go-1.1.12/Gopkg.lock000066400000000000000000000011141420644465700214560ustar00rootroot00000000000000# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. [[projects]] name = "github.com/modern-go/concurrent" packages = ["."] revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a" version = "1.0.0" [[projects]] name = "github.com/modern-go/reflect2" packages = ["."] revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd" version = "1.0.1" [solve-meta] analyzer-name = "dep" analyzer-version = 1 inputs-digest = "ea54a775e5a354cb015502d2e7aa4b74230fc77e894f34a838b268c25ec8eeb8" solver-name = "gps-cdcl" solver-version = 1 golang-github-json-iterator-go-1.1.12/Gopkg.toml000066400000000000000000000013101420644465700214770ustar00rootroot00000000000000# Gopkg.toml example # # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md # for detailed Gopkg.toml documentation. # # required = ["github.com/user/thing/cmd/thing"] # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] # # [[constraint]] # name = "github.com/user/project" # version = "1.0.0" # # [[constraint]] # name = "github.com/user/project2" # branch = "dev" # source = "github.com/myfork/project2" # # [[override]] # name = "github.com/x/y" # version = "2.4.0" ignored = ["github.com/davecgh/go-spew*","github.com/google/gofuzz*","github.com/stretchr/testify*"] [[constraint]] name = "github.com/modern-go/reflect2" version = "1.0.1" golang-github-json-iterator-go-1.1.12/LICENSE000066400000000000000000000020561420644465700205500ustar00rootroot00000000000000MIT License Copyright (c) 2016 json-iterator Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. golang-github-json-iterator-go-1.1.12/README.md000066400000000000000000000055651420644465700210320ustar00rootroot00000000000000[![Sourcegraph](https://sourcegraph.com/github.com/json-iterator/go/-/badge.svg)](https://sourcegraph.com/github.com/json-iterator/go?badge) [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/json-iterator/go) [![Build Status](https://travis-ci.org/json-iterator/go.svg?branch=master)](https://travis-ci.org/json-iterator/go) [![codecov](https://codecov.io/gh/json-iterator/go/branch/master/graph/badge.svg)](https://codecov.io/gh/json-iterator/go) [![rcard](https://goreportcard.com/badge/github.com/json-iterator/go)](https://goreportcard.com/report/github.com/json-iterator/go) [![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/json-iterator/go/master/LICENSE) [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) A high-performance 100% compatible drop-in replacement of "encoding/json" # Benchmark ![benchmark](http://jsoniter.com/benchmarks/go-benchmark.png) Source code: https://github.com/json-iterator/go-benchmark/blob/master/src/github.com/json-iterator/go-benchmark/benchmark_medium_payload_test.go Raw Result (easyjson requires static code generation) | | ns/op | allocation bytes | allocation times | | --------------- | ----------- | ---------------- | ---------------- | | std decode | 35510 ns/op | 1960 B/op | 99 allocs/op | | easyjson decode | 8499 ns/op | 160 B/op | 4 allocs/op | | jsoniter decode | 5623 ns/op | 160 B/op | 3 allocs/op | | std encode | 2213 ns/op | 712 B/op | 5 allocs/op | | 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 Replace ```go import "encoding/json" json.Marshal(&data) ``` with ```go import jsoniter "github.com/json-iterator/go" var json = jsoniter.ConfigCompatibleWithStandardLibrary json.Marshal(&data) ``` Replace ```go import "encoding/json" json.Unmarshal(input, &data) ``` with ```go import jsoniter "github.com/json-iterator/go" var json = jsoniter.ConfigCompatibleWithStandardLibrary json.Unmarshal(input, &data) ``` [More documentation](http://jsoniter.com/migrate-from-go-std.html) # How to get ``` go get github.com/json-iterator/go ``` # Contribution Welcomed ! 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) golang-github-json-iterator-go-1.1.12/adapter.go000066400000000000000000000107661420644465700215210ustar00rootroot00000000000000package jsoniter import ( "bytes" "io" ) // RawMessage to make replace json with jsoniter type RawMessage []byte // Unmarshal adapts to json/encoding Unmarshal API // // Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. // Refer to https://godoc.org/encoding/json#Unmarshal for more information func Unmarshal(data []byte, v interface{}) error { return ConfigDefault.Unmarshal(data, v) } // UnmarshalFromString is a convenient method to read from string instead of []byte func UnmarshalFromString(str string, v interface{}) error { return ConfigDefault.UnmarshalFromString(str, v) } // Get quick method to get value from deeply nested JSON structure func Get(data []byte, path ...interface{}) Any { return ConfigDefault.Get(data, path...) } // Marshal adapts to json/encoding Marshal API // // Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API // Refer to https://godoc.org/encoding/json#Marshal for more information func Marshal(v interface{}) ([]byte, error) { return ConfigDefault.Marshal(v) } // MarshalIndent same as json.MarshalIndent. Prefix is not supported. func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { return ConfigDefault.MarshalIndent(v, prefix, indent) } // MarshalToString convenient method to write as string instead of []byte func MarshalToString(v interface{}) (string, error) { return ConfigDefault.MarshalToString(v) } // NewDecoder adapts to json/stream NewDecoder API. // // NewDecoder returns a new decoder that reads from r. // // Instead of a json/encoding Decoder, an Decoder is returned // Refer to https://godoc.org/encoding/json#NewDecoder for more information func NewDecoder(reader io.Reader) *Decoder { return ConfigDefault.NewDecoder(reader) } // Decoder reads and decodes JSON values from an input stream. // Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress) type Decoder struct { iter *Iterator } // Decode decode JSON into interface{} func (adapter *Decoder) Decode(obj interface{}) error { if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil { if !adapter.iter.loadMore() { return io.EOF } } adapter.iter.ReadVal(obj) err := adapter.iter.Error if err == io.EOF { return nil } return adapter.iter.Error } // More is there more? func (adapter *Decoder) More() bool { iter := adapter.iter if iter.Error != nil { return false } c := iter.nextToken() if c == 0 { return false } iter.unreadByte() return c != ']' && c != '}' } // Buffered remaining buffer func (adapter *Decoder) Buffered() io.Reader { remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail] return bytes.NewReader(remaining) } // UseNumber causes the Decoder to unmarshal a number into an interface{} as a // Number instead of as a float64. func (adapter *Decoder) UseNumber() { cfg := adapter.iter.cfg.configBeforeFrozen cfg.UseNumber = true adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) } // DisallowUnknownFields causes the Decoder to return an error when the destination // is a struct and the input contains object keys which do not match any // non-ignored, exported fields in the destination. func (adapter *Decoder) DisallowUnknownFields() { cfg := adapter.iter.cfg.configBeforeFrozen cfg.DisallowUnknownFields = true adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) } // NewEncoder same as json.NewEncoder func NewEncoder(writer io.Writer) *Encoder { return ConfigDefault.NewEncoder(writer) } // Encoder same as json.Encoder type Encoder struct { stream *Stream } // Encode encode interface{} as JSON to io.Writer func (adapter *Encoder) Encode(val interface{}) error { adapter.stream.WriteVal(val) adapter.stream.WriteRaw("\n") adapter.stream.Flush() return adapter.stream.Error } // SetIndent set the indention. Prefix is not supported func (adapter *Encoder) SetIndent(prefix, indent string) { config := adapter.stream.cfg.configBeforeFrozen config.IndentionStep = len(indent) adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) } // SetEscapeHTML escape html by default, set to false to disable func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) { config := adapter.stream.cfg.configBeforeFrozen config.EscapeHTML = escapeHTML adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) } // Valid reports whether data is a valid JSON encoding. func Valid(data []byte) bool { return ConfigDefault.Valid(data) } golang-github-json-iterator-go-1.1.12/any.go000066400000000000000000000160331420644465700206610ustar00rootroot00000000000000package jsoniter import ( "errors" "fmt" "github.com/modern-go/reflect2" "io" "reflect" "strconv" "unsafe" ) // Any generic object representation. // The lazy json implementation holds []byte and parse lazily. type Any interface { LastError() error ValueType() ValueType MustBeValid() Any ToBool() bool ToInt() int ToInt32() int32 ToInt64() int64 ToUint() uint ToUint32() uint32 ToUint64() uint64 ToFloat32() float32 ToFloat64() float64 ToString() string ToVal(val interface{}) Get(path ...interface{}) Any Size() int Keys() []string GetInterface() interface{} WriteTo(stream *Stream) } type baseAny struct{} func (any *baseAny) Get(path ...interface{}) Any { return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} } func (any *baseAny) Size() int { return 0 } func (any *baseAny) Keys() []string { return []string{} } func (any *baseAny) ToVal(obj interface{}) { panic("not implemented") } // WrapInt32 turn int32 into Any interface func WrapInt32(val int32) Any { return &int32Any{baseAny{}, val} } // WrapInt64 turn int64 into Any interface func WrapInt64(val int64) Any { return &int64Any{baseAny{}, val} } // WrapUint32 turn uint32 into Any interface func WrapUint32(val uint32) Any { return &uint32Any{baseAny{}, val} } // WrapUint64 turn uint64 into Any interface func WrapUint64(val uint64) Any { return &uint64Any{baseAny{}, val} } // WrapFloat64 turn float64 into Any interface func WrapFloat64(val float64) Any { return &floatAny{baseAny{}, val} } // WrapString turn string into Any interface func WrapString(val string) Any { return &stringAny{baseAny{}, val} } // Wrap turn a go object into Any interface func Wrap(val interface{}) Any { if val == nil { return &nilAny{} } asAny, isAny := val.(Any) if isAny { return asAny } typ := reflect2.TypeOf(val) switch typ.Kind() { case reflect.Slice: return wrapArray(val) case reflect.Struct: return wrapStruct(val) case reflect.Map: return wrapMap(val) case reflect.String: return WrapString(val.(string)) case reflect.Int: if strconv.IntSize == 32 { return WrapInt32(int32(val.(int))) } return WrapInt64(int64(val.(int))) case reflect.Int8: return WrapInt32(int32(val.(int8))) case reflect.Int16: return WrapInt32(int32(val.(int16))) case reflect.Int32: return WrapInt32(val.(int32)) case reflect.Int64: return WrapInt64(val.(int64)) case reflect.Uint: if strconv.IntSize == 32 { return WrapUint32(uint32(val.(uint))) } return WrapUint64(uint64(val.(uint))) case reflect.Uintptr: if ptrSize == 32 { return WrapUint32(uint32(val.(uintptr))) } return WrapUint64(uint64(val.(uintptr))) case reflect.Uint8: return WrapUint32(uint32(val.(uint8))) case reflect.Uint16: return WrapUint32(uint32(val.(uint16))) case reflect.Uint32: return WrapUint32(uint32(val.(uint32))) case reflect.Uint64: return WrapUint64(val.(uint64)) case reflect.Float32: return WrapFloat64(float64(val.(float32))) case reflect.Float64: return WrapFloat64(val.(float64)) case reflect.Bool: if val.(bool) == true { return &trueAny{} } return &falseAny{} } return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)} } // ReadAny read next JSON element as an Any object. It is a better json.RawMessage. func (iter *Iterator) ReadAny() Any { return iter.readAny() } func (iter *Iterator) readAny() Any { c := iter.nextToken() switch c { case '"': iter.unreadByte() return &stringAny{baseAny{}, iter.ReadString()} case 'n': iter.skipThreeBytes('u', 'l', 'l') // null return &nilAny{} case 't': iter.skipThreeBytes('r', 'u', 'e') // true return &trueAny{} case 'f': iter.skipFourBytes('a', 'l', 's', 'e') // false return &falseAny{} case '{': return iter.readObjectAny() case '[': return iter.readArrayAny() case '-': return iter.readNumberAny(false) case 0: return &invalidAny{baseAny{}, errors.New("input is empty")} default: return iter.readNumberAny(true) } } func (iter *Iterator) readNumberAny(positive bool) Any { iter.startCapture(iter.head - 1) iter.skipNumber() lazyBuf := iter.stopCapture() return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} } func (iter *Iterator) readObjectAny() Any { iter.startCapture(iter.head - 1) iter.skipObject() lazyBuf := iter.stopCapture() return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} } func (iter *Iterator) readArrayAny() Any { iter.startCapture(iter.head - 1) iter.skipArray() lazyBuf := iter.stopCapture() return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} } func locateObjectField(iter *Iterator, target string) []byte { var found []byte iter.ReadObjectCB(func(iter *Iterator, field string) bool { if field == target { found = iter.SkipAndReturnBytes() return false } iter.Skip() return true }) return found } func locateArrayElement(iter *Iterator, target int) []byte { var found []byte n := 0 iter.ReadArrayCB(func(iter *Iterator) bool { if n == target { found = iter.SkipAndReturnBytes() return false } iter.Skip() n++ return true }) return found } func locatePath(iter *Iterator, path []interface{}) Any { for i, pathKeyObj := range path { switch pathKey := pathKeyObj.(type) { case string: valueBytes := locateObjectField(iter, pathKey) if valueBytes == nil { return newInvalidAny(path[i:]) } iter.ResetBytes(valueBytes) case int: valueBytes := locateArrayElement(iter, pathKey) if valueBytes == nil { return newInvalidAny(path[i:]) } iter.ResetBytes(valueBytes) case int32: if '*' == pathKey { return iter.readAny().Get(path[i:]...) } return newInvalidAny(path[i:]) default: return newInvalidAny(path[i:]) } } if iter.Error != nil && iter.Error != io.EOF { return &invalidAny{baseAny{}, iter.Error} } return iter.readAny() } var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem() func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder { if typ == anyType { return &directAnyCodec{} } if typ.Implements(anyType) { return &anyCodec{ valType: typ, } } return nil } func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder { if typ == anyType { return &directAnyCodec{} } if typ.Implements(anyType) { return &anyCodec{ valType: typ, } } return nil } type anyCodec struct { valType reflect2.Type } func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { panic("not implemented") } func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { obj := codec.valType.UnsafeIndirect(ptr) any := obj.(Any) any.WriteTo(stream) } func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool { obj := codec.valType.UnsafeIndirect(ptr) any := obj.(Any) return any.Size() == 0 } type directAnyCodec struct { } func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { *(*Any)(ptr) = iter.readAny() } func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { any := *(*Any)(ptr) if any == nil { stream.WriteNil() return } any.WriteTo(stream) } func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool { any := *(*Any)(ptr) return any.Size() == 0 } golang-github-json-iterator-go-1.1.12/any_array.go000066400000000000000000000113461420644465700220610ustar00rootroot00000000000000package jsoniter import ( "reflect" "unsafe" ) type arrayLazyAny struct { baseAny cfg *frozenConfig buf []byte err error } func (any *arrayLazyAny) ValueType() ValueType { return ArrayValue } func (any *arrayLazyAny) MustBeValid() Any { return any } func (any *arrayLazyAny) LastError() error { return any.err } func (any *arrayLazyAny) ToBool() bool { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) return iter.ReadArray() } func (any *arrayLazyAny) ToInt() int { if any.ToBool() { return 1 } return 0 } func (any *arrayLazyAny) ToInt32() int32 { if any.ToBool() { return 1 } return 0 } func (any *arrayLazyAny) ToInt64() int64 { if any.ToBool() { return 1 } return 0 } func (any *arrayLazyAny) ToUint() uint { if any.ToBool() { return 1 } return 0 } func (any *arrayLazyAny) ToUint32() uint32 { if any.ToBool() { return 1 } return 0 } func (any *arrayLazyAny) ToUint64() uint64 { if any.ToBool() { return 1 } return 0 } func (any *arrayLazyAny) ToFloat32() float32 { if any.ToBool() { return 1 } return 0 } func (any *arrayLazyAny) ToFloat64() float64 { if any.ToBool() { return 1 } return 0 } func (any *arrayLazyAny) ToString() string { return *(*string)(unsafe.Pointer(&any.buf)) } func (any *arrayLazyAny) ToVal(val interface{}) { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) iter.ReadVal(val) } func (any *arrayLazyAny) Get(path ...interface{}) Any { if len(path) == 0 { return any } switch firstPath := path[0].(type) { case int: iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) valueBytes := locateArrayElement(iter, firstPath) if valueBytes == nil { return newInvalidAny(path) } iter.ResetBytes(valueBytes) return locatePath(iter, path[1:]) case int32: if '*' == firstPath { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) arr := make([]Any, 0) iter.ReadArrayCB(func(iter *Iterator) bool { found := iter.readAny().Get(path[1:]...) if found.ValueType() != InvalidValue { arr = append(arr, found) } return true }) return wrapArray(arr) } return newInvalidAny(path) default: return newInvalidAny(path) } } func (any *arrayLazyAny) Size() int { size := 0 iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) iter.ReadArrayCB(func(iter *Iterator) bool { size++ iter.Skip() return true }) return size } func (any *arrayLazyAny) WriteTo(stream *Stream) { stream.Write(any.buf) } func (any *arrayLazyAny) GetInterface() interface{} { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) return iter.Read() } type arrayAny struct { baseAny val reflect.Value } func wrapArray(val interface{}) *arrayAny { return &arrayAny{baseAny{}, reflect.ValueOf(val)} } func (any *arrayAny) ValueType() ValueType { return ArrayValue } func (any *arrayAny) MustBeValid() Any { return any } func (any *arrayAny) LastError() error { return nil } func (any *arrayAny) ToBool() bool { return any.val.Len() != 0 } func (any *arrayAny) ToInt() int { if any.val.Len() == 0 { return 0 } return 1 } func (any *arrayAny) ToInt32() int32 { if any.val.Len() == 0 { return 0 } return 1 } func (any *arrayAny) ToInt64() int64 { if any.val.Len() == 0 { return 0 } return 1 } func (any *arrayAny) ToUint() uint { if any.val.Len() == 0 { return 0 } return 1 } func (any *arrayAny) ToUint32() uint32 { if any.val.Len() == 0 { return 0 } return 1 } func (any *arrayAny) ToUint64() uint64 { if any.val.Len() == 0 { return 0 } return 1 } func (any *arrayAny) ToFloat32() float32 { if any.val.Len() == 0 { return 0 } return 1 } func (any *arrayAny) ToFloat64() float64 { if any.val.Len() == 0 { return 0 } return 1 } func (any *arrayAny) ToString() string { str, _ := MarshalToString(any.val.Interface()) return str } func (any *arrayAny) Get(path ...interface{}) Any { if len(path) == 0 { return any } switch firstPath := path[0].(type) { case int: if firstPath < 0 || firstPath >= any.val.Len() { return newInvalidAny(path) } return Wrap(any.val.Index(firstPath).Interface()) case int32: if '*' == firstPath { mappedAll := make([]Any, 0) for i := 0; i < any.val.Len(); i++ { mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...) if mapped.ValueType() != InvalidValue { mappedAll = append(mappedAll, mapped) } } return wrapArray(mappedAll) } return newInvalidAny(path) default: return newInvalidAny(path) } } func (any *arrayAny) Size() int { return any.val.Len() } func (any *arrayAny) WriteTo(stream *Stream) { stream.WriteVal(any.val) } func (any *arrayAny) GetInterface() interface{} { return any.val.Interface() } golang-github-json-iterator-go-1.1.12/any_bool.go000066400000000000000000000035321420644465700216740ustar00rootroot00000000000000package jsoniter type trueAny struct { baseAny } func (any *trueAny) LastError() error { return nil } func (any *trueAny) ToBool() bool { return true } func (any *trueAny) ToInt() int { return 1 } func (any *trueAny) ToInt32() int32 { return 1 } func (any *trueAny) ToInt64() int64 { return 1 } func (any *trueAny) ToUint() uint { return 1 } func (any *trueAny) ToUint32() uint32 { return 1 } func (any *trueAny) ToUint64() uint64 { return 1 } func (any *trueAny) ToFloat32() float32 { return 1 } func (any *trueAny) ToFloat64() float64 { return 1 } func (any *trueAny) ToString() string { return "true" } func (any *trueAny) WriteTo(stream *Stream) { stream.WriteTrue() } func (any *trueAny) Parse() *Iterator { return nil } func (any *trueAny) GetInterface() interface{} { return true } func (any *trueAny) ValueType() ValueType { return BoolValue } func (any *trueAny) MustBeValid() Any { return any } type falseAny struct { baseAny } func (any *falseAny) LastError() error { return nil } func (any *falseAny) ToBool() bool { return false } func (any *falseAny) ToInt() int { return 0 } func (any *falseAny) ToInt32() int32 { return 0 } func (any *falseAny) ToInt64() int64 { return 0 } func (any *falseAny) ToUint() uint { return 0 } func (any *falseAny) ToUint32() uint32 { return 0 } func (any *falseAny) ToUint64() uint64 { return 0 } func (any *falseAny) ToFloat32() float32 { return 0 } func (any *falseAny) ToFloat64() float64 { return 0 } func (any *falseAny) ToString() string { return "false" } func (any *falseAny) WriteTo(stream *Stream) { stream.WriteFalse() } func (any *falseAny) Parse() *Iterator { return nil } func (any *falseAny) GetInterface() interface{} { return false } func (any *falseAny) ValueType() ValueType { return BoolValue } func (any *falseAny) MustBeValid() Any { return any } golang-github-json-iterator-go-1.1.12/any_float.go000066400000000000000000000023441420644465700220460ustar00rootroot00000000000000package jsoniter import ( "strconv" ) type floatAny struct { baseAny val float64 } func (any *floatAny) Parse() *Iterator { return nil } func (any *floatAny) ValueType() ValueType { return NumberValue } func (any *floatAny) MustBeValid() Any { return any } func (any *floatAny) LastError() error { return nil } func (any *floatAny) ToBool() bool { return any.ToFloat64() != 0 } func (any *floatAny) ToInt() int { return int(any.val) } func (any *floatAny) ToInt32() int32 { return int32(any.val) } func (any *floatAny) ToInt64() int64 { return int64(any.val) } func (any *floatAny) ToUint() uint { if any.val > 0 { return uint(any.val) } return 0 } func (any *floatAny) ToUint32() uint32 { if any.val > 0 { return uint32(any.val) } return 0 } func (any *floatAny) ToUint64() uint64 { if any.val > 0 { return uint64(any.val) } return 0 } func (any *floatAny) ToFloat32() float32 { return float32(any.val) } func (any *floatAny) ToFloat64() float64 { return any.val } func (any *floatAny) ToString() string { return strconv.FormatFloat(any.val, 'E', -1, 64) } func (any *floatAny) WriteTo(stream *Stream) { stream.WriteFloat64(any.val) } func (any *floatAny) GetInterface() interface{} { return any.val } golang-github-json-iterator-go-1.1.12/any_int32.go000066400000000000000000000021661420644465700217020ustar00rootroot00000000000000package jsoniter import ( "strconv" ) type int32Any struct { baseAny val int32 } func (any *int32Any) LastError() error { return nil } func (any *int32Any) ValueType() ValueType { return NumberValue } func (any *int32Any) MustBeValid() Any { return any } func (any *int32Any) ToBool() bool { return any.val != 0 } func (any *int32Any) ToInt() int { return int(any.val) } func (any *int32Any) ToInt32() int32 { return any.val } func (any *int32Any) ToInt64() int64 { return int64(any.val) } func (any *int32Any) ToUint() uint { return uint(any.val) } func (any *int32Any) ToUint32() uint32 { return uint32(any.val) } func (any *int32Any) ToUint64() uint64 { return uint64(any.val) } func (any *int32Any) ToFloat32() float32 { return float32(any.val) } func (any *int32Any) ToFloat64() float64 { return float64(any.val) } func (any *int32Any) ToString() string { return strconv.FormatInt(int64(any.val), 10) } func (any *int32Any) WriteTo(stream *Stream) { stream.WriteInt32(any.val) } func (any *int32Any) Parse() *Iterator { return nil } func (any *int32Any) GetInterface() interface{} { return any.val } golang-github-json-iterator-go-1.1.12/any_int64.go000066400000000000000000000021571420644465700217070ustar00rootroot00000000000000package jsoniter import ( "strconv" ) type int64Any struct { baseAny val int64 } func (any *int64Any) LastError() error { return nil } func (any *int64Any) ValueType() ValueType { return NumberValue } func (any *int64Any) MustBeValid() Any { return any } func (any *int64Any) ToBool() bool { return any.val != 0 } func (any *int64Any) ToInt() int { return int(any.val) } func (any *int64Any) ToInt32() int32 { return int32(any.val) } func (any *int64Any) ToInt64() int64 { return any.val } func (any *int64Any) ToUint() uint { return uint(any.val) } func (any *int64Any) ToUint32() uint32 { return uint32(any.val) } func (any *int64Any) ToUint64() uint64 { return uint64(any.val) } func (any *int64Any) ToFloat32() float32 { return float32(any.val) } func (any *int64Any) ToFloat64() float64 { return float64(any.val) } func (any *int64Any) ToString() string { return strconv.FormatInt(any.val, 10) } func (any *int64Any) WriteTo(stream *Stream) { stream.WriteInt64(any.val) } func (any *int64Any) Parse() *Iterator { return nil } func (any *int64Any) GetInterface() interface{} { return any.val } golang-github-json-iterator-go-1.1.12/any_invalid.go000066400000000000000000000025221420644465700223650ustar00rootroot00000000000000package jsoniter import "fmt" type invalidAny struct { baseAny err error } func newInvalidAny(path []interface{}) *invalidAny { return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)} } func (any *invalidAny) LastError() error { return any.err } func (any *invalidAny) ValueType() ValueType { return InvalidValue } func (any *invalidAny) MustBeValid() Any { panic(any.err) } func (any *invalidAny) ToBool() bool { return false } func (any *invalidAny) ToInt() int { return 0 } func (any *invalidAny) ToInt32() int32 { return 0 } func (any *invalidAny) ToInt64() int64 { return 0 } func (any *invalidAny) ToUint() uint { return 0 } func (any *invalidAny) ToUint32() uint32 { return 0 } func (any *invalidAny) ToUint64() uint64 { return 0 } func (any *invalidAny) ToFloat32() float32 { return 0 } func (any *invalidAny) ToFloat64() float64 { return 0 } func (any *invalidAny) ToString() string { return "" } func (any *invalidAny) WriteTo(stream *Stream) { } func (any *invalidAny) Get(path ...interface{}) Any { if any.err == nil { return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)} } return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)} } func (any *invalidAny) Parse() *Iterator { return nil } func (any *invalidAny) GetInterface() interface{} { return nil } golang-github-json-iterator-go-1.1.12/any_nil.go000066400000000000000000000016241420644465700215230ustar00rootroot00000000000000package jsoniter type nilAny struct { baseAny } func (any *nilAny) LastError() error { return nil } func (any *nilAny) ValueType() ValueType { return NilValue } func (any *nilAny) MustBeValid() Any { return any } func (any *nilAny) ToBool() bool { return false } func (any *nilAny) ToInt() int { return 0 } func (any *nilAny) ToInt32() int32 { return 0 } func (any *nilAny) ToInt64() int64 { return 0 } func (any *nilAny) ToUint() uint { return 0 } func (any *nilAny) ToUint32() uint32 { return 0 } func (any *nilAny) ToUint64() uint64 { return 0 } func (any *nilAny) ToFloat32() float32 { return 0 } func (any *nilAny) ToFloat64() float64 { return 0 } func (any *nilAny) ToString() string { return "" } func (any *nilAny) WriteTo(stream *Stream) { stream.WriteNil() } func (any *nilAny) Parse() *Iterator { return nil } func (any *nilAny) GetInterface() interface{} { return nil } golang-github-json-iterator-go-1.1.12/any_number.go000066400000000000000000000050701420644465700222300ustar00rootroot00000000000000package jsoniter import ( "io" "unsafe" ) type numberLazyAny struct { baseAny cfg *frozenConfig buf []byte err error } func (any *numberLazyAny) ValueType() ValueType { return NumberValue } func (any *numberLazyAny) MustBeValid() Any { return any } func (any *numberLazyAny) LastError() error { return any.err } func (any *numberLazyAny) ToBool() bool { return any.ToFloat64() != 0 } func (any *numberLazyAny) ToInt() int { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadInt() if iter.Error != nil && iter.Error != io.EOF { any.err = iter.Error } return val } func (any *numberLazyAny) ToInt32() int32 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadInt32() if iter.Error != nil && iter.Error != io.EOF { any.err = iter.Error } return val } func (any *numberLazyAny) ToInt64() int64 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadInt64() if iter.Error != nil && iter.Error != io.EOF { any.err = iter.Error } return val } func (any *numberLazyAny) ToUint() uint { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadUint() if iter.Error != nil && iter.Error != io.EOF { any.err = iter.Error } return val } func (any *numberLazyAny) ToUint32() uint32 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadUint32() if iter.Error != nil && iter.Error != io.EOF { any.err = iter.Error } return val } func (any *numberLazyAny) ToUint64() uint64 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadUint64() if iter.Error != nil && iter.Error != io.EOF { any.err = iter.Error } return val } func (any *numberLazyAny) ToFloat32() float32 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadFloat32() if iter.Error != nil && iter.Error != io.EOF { any.err = iter.Error } return val } func (any *numberLazyAny) ToFloat64() float64 { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) val := iter.ReadFloat64() if iter.Error != nil && iter.Error != io.EOF { any.err = iter.Error } return val } func (any *numberLazyAny) ToString() string { return *(*string)(unsafe.Pointer(&any.buf)) } func (any *numberLazyAny) WriteTo(stream *Stream) { stream.Write(any.buf) } func (any *numberLazyAny) GetInterface() interface{} { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) return iter.Read() } golang-github-json-iterator-go-1.1.12/any_object.go000066400000000000000000000154311420644465700222100ustar00rootroot00000000000000package jsoniter import ( "reflect" "unsafe" ) type objectLazyAny struct { baseAny cfg *frozenConfig buf []byte err error } func (any *objectLazyAny) ValueType() ValueType { return ObjectValue } func (any *objectLazyAny) MustBeValid() Any { return any } func (any *objectLazyAny) LastError() error { return any.err } func (any *objectLazyAny) ToBool() bool { return true } func (any *objectLazyAny) ToInt() int { return 0 } func (any *objectLazyAny) ToInt32() int32 { return 0 } func (any *objectLazyAny) ToInt64() int64 { return 0 } func (any *objectLazyAny) ToUint() uint { return 0 } func (any *objectLazyAny) ToUint32() uint32 { return 0 } func (any *objectLazyAny) ToUint64() uint64 { return 0 } func (any *objectLazyAny) ToFloat32() float32 { return 0 } func (any *objectLazyAny) ToFloat64() float64 { return 0 } func (any *objectLazyAny) ToString() string { return *(*string)(unsafe.Pointer(&any.buf)) } func (any *objectLazyAny) ToVal(obj interface{}) { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) iter.ReadVal(obj) } func (any *objectLazyAny) Get(path ...interface{}) Any { if len(path) == 0 { return any } switch firstPath := path[0].(type) { case string: iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) valueBytes := locateObjectField(iter, firstPath) if valueBytes == nil { return newInvalidAny(path) } iter.ResetBytes(valueBytes) return locatePath(iter, path[1:]) case int32: if '*' == firstPath { mappedAll := map[string]Any{} iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) iter.ReadMapCB(func(iter *Iterator, field string) bool { mapped := locatePath(iter, path[1:]) if mapped.ValueType() != InvalidValue { mappedAll[field] = mapped } return true }) return wrapMap(mappedAll) } return newInvalidAny(path) default: return newInvalidAny(path) } } func (any *objectLazyAny) Keys() []string { keys := []string{} iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) iter.ReadMapCB(func(iter *Iterator, field string) bool { iter.Skip() keys = append(keys, field) return true }) return keys } func (any *objectLazyAny) Size() int { size := 0 iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) iter.ReadObjectCB(func(iter *Iterator, field string) bool { iter.Skip() size++ return true }) return size } func (any *objectLazyAny) WriteTo(stream *Stream) { stream.Write(any.buf) } func (any *objectLazyAny) GetInterface() interface{} { iter := any.cfg.BorrowIterator(any.buf) defer any.cfg.ReturnIterator(iter) return iter.Read() } type objectAny struct { baseAny err error val reflect.Value } func wrapStruct(val interface{}) *objectAny { return &objectAny{baseAny{}, nil, reflect.ValueOf(val)} } func (any *objectAny) ValueType() ValueType { return ObjectValue } func (any *objectAny) MustBeValid() Any { return any } func (any *objectAny) Parse() *Iterator { return nil } func (any *objectAny) LastError() error { return any.err } func (any *objectAny) ToBool() bool { return any.val.NumField() != 0 } func (any *objectAny) ToInt() int { return 0 } func (any *objectAny) ToInt32() int32 { return 0 } func (any *objectAny) ToInt64() int64 { return 0 } func (any *objectAny) ToUint() uint { return 0 } func (any *objectAny) ToUint32() uint32 { return 0 } func (any *objectAny) ToUint64() uint64 { return 0 } func (any *objectAny) ToFloat32() float32 { return 0 } func (any *objectAny) ToFloat64() float64 { return 0 } func (any *objectAny) ToString() string { str, err := MarshalToString(any.val.Interface()) any.err = err return str } func (any *objectAny) Get(path ...interface{}) Any { if len(path) == 0 { return any } switch firstPath := path[0].(type) { case string: field := any.val.FieldByName(firstPath) if !field.IsValid() { return newInvalidAny(path) } return Wrap(field.Interface()) case int32: if '*' == firstPath { mappedAll := map[string]Any{} for i := 0; i < any.val.NumField(); i++ { field := any.val.Field(i) if field.CanInterface() { mapped := Wrap(field.Interface()).Get(path[1:]...) if mapped.ValueType() != InvalidValue { mappedAll[any.val.Type().Field(i).Name] = mapped } } } return wrapMap(mappedAll) } return newInvalidAny(path) default: return newInvalidAny(path) } } func (any *objectAny) Keys() []string { keys := make([]string, 0, any.val.NumField()) for i := 0; i < any.val.NumField(); i++ { keys = append(keys, any.val.Type().Field(i).Name) } return keys } func (any *objectAny) Size() int { return any.val.NumField() } func (any *objectAny) WriteTo(stream *Stream) { stream.WriteVal(any.val) } func (any *objectAny) GetInterface() interface{} { return any.val.Interface() } type mapAny struct { baseAny err error val reflect.Value } func wrapMap(val interface{}) *mapAny { return &mapAny{baseAny{}, nil, reflect.ValueOf(val)} } func (any *mapAny) ValueType() ValueType { return ObjectValue } func (any *mapAny) MustBeValid() Any { return any } func (any *mapAny) Parse() *Iterator { return nil } func (any *mapAny) LastError() error { return any.err } func (any *mapAny) ToBool() bool { return true } func (any *mapAny) ToInt() int { return 0 } func (any *mapAny) ToInt32() int32 { return 0 } func (any *mapAny) ToInt64() int64 { return 0 } func (any *mapAny) ToUint() uint { return 0 } func (any *mapAny) ToUint32() uint32 { return 0 } func (any *mapAny) ToUint64() uint64 { return 0 } func (any *mapAny) ToFloat32() float32 { return 0 } func (any *mapAny) ToFloat64() float64 { return 0 } func (any *mapAny) ToString() string { str, err := MarshalToString(any.val.Interface()) any.err = err return str } func (any *mapAny) Get(path ...interface{}) Any { if len(path) == 0 { return any } switch firstPath := path[0].(type) { case int32: if '*' == firstPath { mappedAll := map[string]Any{} for _, key := range any.val.MapKeys() { keyAsStr := key.String() element := Wrap(any.val.MapIndex(key).Interface()) mapped := element.Get(path[1:]...) if mapped.ValueType() != InvalidValue { mappedAll[keyAsStr] = mapped } } return wrapMap(mappedAll) } return newInvalidAny(path) default: value := any.val.MapIndex(reflect.ValueOf(firstPath)) if !value.IsValid() { return newInvalidAny(path) } return Wrap(value.Interface()) } } func (any *mapAny) Keys() []string { keys := make([]string, 0, any.val.Len()) for _, key := range any.val.MapKeys() { keys = append(keys, key.String()) } return keys } func (any *mapAny) Size() int { return any.val.Len() } func (any *mapAny) WriteTo(stream *Stream) { stream.WriteVal(any.val) } func (any *mapAny) GetInterface() interface{} { return any.val.Interface() } golang-github-json-iterator-go-1.1.12/any_str.go000066400000000000000000000055151420644465700215540ustar00rootroot00000000000000package jsoniter import ( "fmt" "strconv" ) type stringAny struct { baseAny val string } func (any *stringAny) Get(path ...interface{}) Any { if len(path) == 0 { return any } return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} } func (any *stringAny) Parse() *Iterator { return nil } func (any *stringAny) ValueType() ValueType { return StringValue } func (any *stringAny) MustBeValid() Any { return any } func (any *stringAny) LastError() error { return nil } func (any *stringAny) ToBool() bool { str := any.ToString() if str == "0" { return false } for _, c := range str { switch c { case ' ', '\n', '\r', '\t': default: return true } } return false } func (any *stringAny) ToInt() int { return int(any.ToInt64()) } func (any *stringAny) ToInt32() int32 { return int32(any.ToInt64()) } func (any *stringAny) ToInt64() int64 { if any.val == "" { return 0 } flag := 1 startPos := 0 if any.val[0] == '+' || any.val[0] == '-' { startPos = 1 } if any.val[0] == '-' { flag = -1 } endPos := startPos for i := startPos; i < len(any.val); i++ { if any.val[i] >= '0' && any.val[i] <= '9' { endPos = i + 1 } else { break } } parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64) return int64(flag) * parsed } func (any *stringAny) ToUint() uint { return uint(any.ToUint64()) } func (any *stringAny) ToUint32() uint32 { return uint32(any.ToUint64()) } func (any *stringAny) ToUint64() uint64 { if any.val == "" { return 0 } startPos := 0 if any.val[0] == '-' { return 0 } if any.val[0] == '+' { startPos = 1 } endPos := startPos for i := startPos; i < len(any.val); i++ { if any.val[i] >= '0' && any.val[i] <= '9' { endPos = i + 1 } else { break } } parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64) return parsed } func (any *stringAny) ToFloat32() float32 { return float32(any.ToFloat64()) } func (any *stringAny) ToFloat64() float64 { if len(any.val) == 0 { return 0 } // first char invalid if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') { return 0 } // extract valid num expression from string // eg 123true => 123, -12.12xxa => -12.12 endPos := 1 for i := 1; i < len(any.val); i++ { if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' { endPos = i + 1 continue } // end position is the first char which is not digit if any.val[i] >= '0' && any.val[i] <= '9' { endPos = i + 1 } else { endPos = i break } } parsed, _ := strconv.ParseFloat(any.val[:endPos], 64) return parsed } func (any *stringAny) ToString() string { return any.val } func (any *stringAny) WriteTo(stream *Stream) { stream.WriteString(any.val) } func (any *stringAny) GetInterface() interface{} { return any.val } golang-github-json-iterator-go-1.1.12/any_tests/000077500000000000000000000000001420644465700215515ustar00rootroot00000000000000golang-github-json-iterator-go-1.1.12/any_tests/jsoniter_any_array_test.go000066400000000000000000000072411420644465700270450ustar00rootroot00000000000000package any_tests import ( "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_read_empty_array_as_any(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("[]")) should.Equal(jsoniter.ArrayValue, any.Get().ValueType()) should.Equal(jsoniter.InvalidValue, any.Get(0.3).ValueType()) should.Equal(0, any.Size()) should.Equal(jsoniter.ArrayValue, any.ValueType()) should.Nil(any.LastError()) should.Equal(0, any.ToInt()) should.Equal(int32(0), any.ToInt32()) should.Equal(int64(0), any.ToInt64()) should.Equal(uint(0), any.ToUint()) should.Equal(uint32(0), any.ToUint32()) should.Equal(uint64(0), any.ToUint64()) should.Equal(float32(0), any.ToFloat32()) should.Equal(float64(0), any.ToFloat64()) } func Test_read_one_element_array_as_any(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("[1]")) should.Equal(1, any.Size()) } func Test_read_two_element_array_as_any(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("[1,2]")) should.Equal(1, any.Get(0).ToInt()) should.Equal(2, any.Size()) should.True(any.ToBool()) should.Equal(1, any.ToInt()) should.Equal([]interface{}{float64(1), float64(2)}, any.GetInterface()) stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32) any.WriteTo(stream) should.Equal("[1,2]", string(stream.Buffer())) arr := []int{} any.ToVal(&arr) should.Equal([]int{1, 2}, arr) } func Test_wrap_array_and_convert_to_any(t *testing.T) { should := require.New(t) any := jsoniter.Wrap([]int{1, 2, 3}) any2 := jsoniter.Wrap([]int{}) should.Equal("[1,2,3]", any.ToString()) should.True(any.ToBool()) should.False(any2.ToBool()) should.Equal(1, any.ToInt()) should.Equal(0, any2.ToInt()) should.Equal(int32(1), any.ToInt32()) should.Equal(int32(0), any2.ToInt32()) should.Equal(int64(1), any.ToInt64()) should.Equal(int64(0), any2.ToInt64()) should.Equal(uint(1), any.ToUint()) should.Equal(uint(0), any2.ToUint()) should.Equal(uint32(1), any.ToUint32()) should.Equal(uint32(0), any2.ToUint32()) should.Equal(uint64(1), any.ToUint64()) should.Equal(uint64(0), any2.ToUint64()) should.Equal(float32(1), any.ToFloat32()) should.Equal(float32(0), any2.ToFloat32()) should.Equal(float64(1), any.ToFloat64()) should.Equal(float64(0), any2.ToFloat64()) should.Equal(3, any.Size()) should.Equal(0, any2.Size()) var i interface{} = []int{1, 2, 3} should.Equal(i, any.GetInterface()) } func Test_array_lazy_any_get(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("[1,[2,3],4]")) should.Equal(3, any.Get(1, 1).ToInt()) should.Equal("[1,[2,3],4]", any.ToString()) } func Test_array_lazy_any_get_all(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("[[1],[2],[3,4]]")) should.Equal("[1,2,3]", any.Get('*', 0).ToString()) any = jsoniter.Get([]byte("[[[1],[2],[3,4]]]"), 0, '*', 0) should.Equal("[1,2,3]", any.ToString()) } func Test_array_wrapper_any_get_all(t *testing.T) { should := require.New(t) any := jsoniter.Wrap([][]int{ {1, 2}, {3, 4}, {5, 6}, }) should.Equal("[1,3,5]", any.Get('*', 0).ToString()) should.Equal(jsoniter.ArrayValue, any.ValueType()) should.True(any.ToBool()) should.Equal(1, any.Get(0, 0).ToInt()) } func Test_array_lazy_any_get_invalid(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("[]")) should.Equal(jsoniter.InvalidValue, any.Get(1, 1).ValueType()) should.NotNil(any.Get(1, 1).LastError()) should.Equal(jsoniter.InvalidValue, any.Get("1").ValueType()) should.NotNil(any.Get("1").LastError()) } func Test_invalid_array(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("["), 0) should.Equal(jsoniter.InvalidValue, any.ValueType()) } golang-github-json-iterator-go-1.1.12/any_tests/jsoniter_any_bool_test.go000066400000000000000000000025041420644465700266570ustar00rootroot00000000000000package any_tests import ( "fmt" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) var boolConvertMap = map[string]bool{ "null": false, "true": true, "false": false, `"true"`: true, `"false"`: true, "123": true, `"123"`: true, "0": false, `"0"`: false, "-1": true, `"-1"`: true, "1.1": true, "0.0": false, "-1.1": true, `""`: false, "[1,2]": true, "[]": false, "{}": true, `{"abc":1}`: true, } func Test_read_bool_as_any(t *testing.T) { should := require.New(t) var any jsoniter.Any for k, v := range boolConvertMap { any = jsoniter.Get([]byte(k)) if v { should.True(any.ToBool(), fmt.Sprintf("origin val is %v", k)) } else { should.False(any.ToBool(), fmt.Sprintf("origin val is %v", k)) } } } func Test_write_bool_to_stream(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("true")) stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32) any.WriteTo(stream) should.Equal("true", string(stream.Buffer())) should.Equal(any.ValueType(), jsoniter.BoolValue) any = jsoniter.Get([]byte("false")) stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32) any.WriteTo(stream) should.Equal("false", string(stream.Buffer())) should.Equal(any.ValueType(), jsoniter.BoolValue) } golang-github-json-iterator-go-1.1.12/any_tests/jsoniter_any_float_test.go000066400000000000000000000040531420644465700270320ustar00rootroot00000000000000package any_tests import ( "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) var floatConvertMap = map[string]float64{ "null": 0, "true": 1, "false": 0, `"true"`: 0, `"false"`: 0, "1e1": 10, "1e+1": 10, "1e-1": .1, "1E1": 10, "1E+1": 10, "1E-1": .1, "-1e1": -10, "-1e+1": -10, "-1e-1": -.1, "-1E1": -10, "-1E+1": -10, "-1E-1": -.1, `"1e1"`: 10, `"1e+1"`: 10, `"1e-1"`: .1, `"1E1"`: 10, `"1E+1"`: 10, `"1E-1"`: .1, `"-1e1"`: -10, `"-1e+1"`: -10, `"-1e-1"`: -.1, `"-1E1"`: -10, `"-1E+1"`: -10, `"-1E-1"`: -.1, "123": 123, `"123true"`: 123, `"+"`: 0, `"-"`: 0, `"-123true"`: -123, `"-99.9true"`: -99.9, "0": 0, `"0"`: 0, "-1": -1, "1.1": 1.1, "0.0": 0, "-1.1": -1.1, `"+1.1"`: 1.1, `""`: 0, "[1,2]": 1, "[]": 0, "{}": 0, `{"abc":1}`: 0, } func Test_read_any_to_float(t *testing.T) { should := require.New(t) for k, v := range floatConvertMap { any := jsoniter.Get([]byte(k)) should.Equal(float64(v), any.ToFloat64(), "the original val is "+k) } for k, v := range floatConvertMap { any := jsoniter.Get([]byte(k)) should.Equal(float32(v), any.ToFloat32(), "the original val is "+k) } } func Test_read_float_to_any(t *testing.T) { should := require.New(t) any := jsoniter.WrapFloat64(12.3) anyFloat64 := float64(12.3) any2 := jsoniter.WrapFloat64(-1.1) should.Equal(float64(12.3), any.ToFloat64()) should.True(any.ToBool()) should.Equal(float32(anyFloat64), any.ToFloat32()) should.Equal(int(anyFloat64), any.ToInt()) should.Equal(int32(anyFloat64), any.ToInt32()) should.Equal(int64(anyFloat64), any.ToInt64()) should.Equal(uint(anyFloat64), any.ToUint()) should.Equal(uint32(anyFloat64), any.ToUint32()) should.Equal(uint64(anyFloat64), any.ToUint64()) should.Equal(uint(0), any2.ToUint()) should.Equal(uint32(0), any2.ToUint32()) should.Equal(uint64(0), any2.ToUint64()) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal("1.23E+01", any.ToString()) } golang-github-json-iterator-go-1.1.12/any_tests/jsoniter_any_int_test.go000066400000000000000000000125231420644465700265200ustar00rootroot00000000000000package any_tests import ( "fmt" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) var intConvertMap = map[string]int{ "null": 0, "321.1": 321, "-321.1": -321, `"1.1"`: 1, `"-321.1"`: -321, "0.0": 0, "0": 0, `"0"`: 0, `"0.0"`: 0, "-1.1": -1, "true": 1, "false": 0, `"true"`: 0, `"false"`: 0, `"true123"`: 0, `"123true"`: 123, `"-123true"`: -123, `"1.2332e6"`: 1, `""`: 0, "+": 0, "-": 0, "[]": 0, "[1,2]": 1, `["1","2"]`: 1, // object in php cannot convert to int "{}": 0, } func Test_read_any_to_int(t *testing.T) { should := require.New(t) // int for k, v := range intConvertMap { any := jsoniter.Get([]byte(k)) should.Equal(v, any.ToInt(), fmt.Sprintf("origin val %v", k)) } // int32 for k, v := range intConvertMap { any := jsoniter.Get([]byte(k)) should.Equal(int32(v), any.ToInt32(), fmt.Sprintf("original val is %v", k)) } // int64 for k, v := range intConvertMap { any := jsoniter.Get([]byte(k)) should.Equal(int64(v), any.ToInt64(), fmt.Sprintf("original val is %v", k)) } } var uintConvertMap = map[string]int{ "null": 0, "321.1": 321, `"1.1"`: 1, `"-123.1"`: 0, "0.0": 0, "0": 0, `"0"`: 0, `"0.0"`: 0, `"00.0"`: 0, "true": 1, "false": 0, `"true"`: 0, `"false"`: 0, `"true123"`: 0, `"+1"`: 1, `"123true"`: 123, `"-123true"`: 0, `"1.2332e6"`: 1, `""`: 0, "+": 0, "-": 0, ".": 0, "[]": 0, "[1,2]": 1, "{}": 0, "{1,2}": 0, "-1.1": 0, "-321.1": 0, } func Test_read_any_to_uint(t *testing.T) { should := require.New(t) for k, v := range uintConvertMap { any := jsoniter.Get([]byte(k)) should.Equal(uint64(v), any.ToUint64(), fmt.Sprintf("origin val %v", k)) } for k, v := range uintConvertMap { any := jsoniter.Get([]byte(k)) should.Equal(uint32(v), any.ToUint32(), fmt.Sprintf("origin val %v", k)) } for k, v := range uintConvertMap { any := jsoniter.Get([]byte(k)) should.Equal(uint(v), any.ToUint(), fmt.Sprintf("origin val %v", k)) } } func Test_read_int64_to_any(t *testing.T) { should := require.New(t) any := jsoniter.WrapInt64(12345) should.Equal(12345, any.ToInt()) should.Equal(int32(12345), any.ToInt32()) should.Equal(int64(12345), any.ToInt64()) should.Equal(uint(12345), any.ToUint()) should.Equal(uint32(12345), any.ToUint32()) should.Equal(uint64(12345), any.ToUint64()) should.Equal(float32(12345), any.ToFloat32()) should.Equal(float64(12345), any.ToFloat64()) should.Equal("12345", any.ToString()) should.Equal(true, any.ToBool()) should.Equal(any.ValueType(), jsoniter.NumberValue) stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32) any.WriteTo(stream) should.Equal("12345", string(stream.Buffer())) } func Test_read_int32_to_any(t *testing.T) { should := require.New(t) any := jsoniter.WrapInt32(12345) should.Equal(12345, any.ToInt()) should.Equal(int32(12345), any.ToInt32()) should.Equal(int64(12345), any.ToInt64()) should.Equal(uint(12345), any.ToUint()) should.Equal(uint32(12345), any.ToUint32()) should.Equal(uint64(12345), any.ToUint64()) should.Equal(float32(12345), any.ToFloat32()) should.Equal(float64(12345), any.ToFloat64()) should.Equal("12345", any.ToString()) should.Equal(true, any.ToBool()) should.Equal(any.ValueType(), jsoniter.NumberValue) stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32) any.WriteTo(stream) should.Equal("12345", string(stream.Buffer())) } func Test_read_uint32_to_any(t *testing.T) { should := require.New(t) any := jsoniter.WrapUint32(12345) should.Equal(12345, any.ToInt()) should.Equal(int32(12345), any.ToInt32()) should.Equal(int64(12345), any.ToInt64()) should.Equal(uint(12345), any.ToUint()) should.Equal(uint32(12345), any.ToUint32()) should.Equal(uint64(12345), any.ToUint64()) should.Equal(float32(12345), any.ToFloat32()) should.Equal(float64(12345), any.ToFloat64()) should.Equal("12345", any.ToString()) should.Equal(true, any.ToBool()) should.Equal(any.ValueType(), jsoniter.NumberValue) stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32) any.WriteTo(stream) should.Equal("12345", string(stream.Buffer())) } func Test_read_uint64_to_any(t *testing.T) { should := require.New(t) any := jsoniter.WrapUint64(12345) should.Equal(12345, any.ToInt()) should.Equal(int32(12345), any.ToInt32()) should.Equal(int64(12345), any.ToInt64()) should.Equal(uint(12345), any.ToUint()) should.Equal(uint32(12345), any.ToUint32()) should.Equal(uint64(12345), any.ToUint64()) should.Equal(float32(12345), any.ToFloat32()) should.Equal(float64(12345), any.ToFloat64()) should.Equal("12345", any.ToString()) should.Equal(true, any.ToBool()) should.Equal(any.ValueType(), jsoniter.NumberValue) stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32) any.WriteTo(stream) should.Equal("12345", string(stream.Buffer())) stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32) stream.WriteUint(uint(123)) should.Equal("123", string(stream.Buffer())) } func Test_int_lazy_any_get(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("1234")) // panic!! //should.Equal(any.LastError(), io.EOF) should.Equal(jsoniter.InvalidValue, any.Get(1, "2").ValueType()) } golang-github-json-iterator-go-1.1.12/any_tests/jsoniter_any_map_test.go000066400000000000000000000014041420644465700264770ustar00rootroot00000000000000package any_tests import ( "github.com/json-iterator/go" "github.com/stretchr/testify/require" "testing" ) func Test_wrap_map(t *testing.T) { should := require.New(t) any := jsoniter.Wrap(map[string]string{"Field1": "hello"}) should.Equal("hello", any.Get("Field1").ToString()) any = jsoniter.Wrap(map[string]string{"Field1": "hello"}) should.Equal(1, any.Size()) } func Test_map_wrapper_any_get_all(t *testing.T) { should := require.New(t) any := jsoniter.Wrap(map[string][]int{"Field1": {1, 2}}) should.Equal(`{"Field1":1}`, any.Get('*', 0).ToString()) should.Contains(any.Keys(), "Field1") // map write to stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0) any.WriteTo(stream) // TODO cannot pass //should.Equal(string(stream.buf), "") } golang-github-json-iterator-go-1.1.12/any_tests/jsoniter_any_null_test.go000066400000000000000000000005431420644465700266770ustar00rootroot00000000000000package any_tests import ( "github.com/json-iterator/go" "github.com/stretchr/testify/require" "testing" ) func Test_read_null_as_any(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte(`null`)) should.Equal(0, any.ToInt()) should.Equal(float64(0), any.ToFloat64()) should.Equal("", any.ToString()) should.False(any.ToBool()) } golang-github-json-iterator-go-1.1.12/any_tests/jsoniter_any_object_test.go000066400000000000000000000070271420644465700271770ustar00rootroot00000000000000package any_tests import ( "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_read_object_as_any(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte(`{"a":"stream","c":"d"}`)) should.Equal(`{"a":"stream","c":"d"}`, any.ToString()) // partial parse should.Equal("stream", any.Get("a").ToString()) should.Equal("d", any.Get("c").ToString()) should.Equal(2, len(any.Keys())) any = jsoniter.Get([]byte(`{"a":"stream","c":"d"}`)) // full parse should.Equal(2, len(any.Keys())) should.Equal(2, any.Size()) should.True(any.ToBool()) should.Equal(0, any.ToInt()) should.Equal(jsoniter.ObjectValue, any.ValueType()) should.Nil(any.LastError()) obj := struct { A string }{} any.ToVal(&obj) should.Equal("stream", obj.A) } func Test_object_lazy_any_get(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte(`{"a":{"stream":{"c":"d"}}}`)) should.Equal("d", any.Get("a", "stream", "c").ToString()) } func Test_object_lazy_any_get_all(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte(`{"a":[0],"stream":[1]}`)) should.Contains(any.Get('*', 0).ToString(), `"a":0`) } func Test_object_lazy_any_get_invalid(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte(`{}`)) should.Equal(jsoniter.InvalidValue, any.Get("a", "stream", "c").ValueType()) should.Equal(jsoniter.InvalidValue, any.Get(1).ValueType()) } func Test_wrap_map_and_convert_to_any(t *testing.T) { should := require.New(t) any := jsoniter.Wrap(map[string]interface{}{"a": 1}) should.True(any.ToBool()) should.Equal(0, any.ToInt()) should.Equal(int32(0), any.ToInt32()) should.Equal(int64(0), any.ToInt64()) should.Equal(float32(0), any.ToFloat32()) should.Equal(float64(0), any.ToFloat64()) should.Equal(uint(0), any.ToUint()) should.Equal(uint32(0), any.ToUint32()) should.Equal(uint64(0), any.ToUint64()) } func Test_wrap_object_and_convert_to_any(t *testing.T) { should := require.New(t) type TestObject struct { Field1 string field2 string } any := jsoniter.Wrap(TestObject{"hello", "world"}) should.Equal("hello", any.Get("Field1").ToString()) any = jsoniter.Wrap(TestObject{"hello", "world"}) should.Equal(2, any.Size()) should.Equal(`{"Field1":"hello"}`, any.Get('*').ToString()) should.Equal(0, any.ToInt()) should.Equal(int32(0), any.ToInt32()) should.Equal(int64(0), any.ToInt64()) should.Equal(float32(0), any.ToFloat32()) should.Equal(float64(0), any.ToFloat64()) should.Equal(uint(0), any.ToUint()) should.Equal(uint32(0), any.ToUint32()) should.Equal(uint64(0), any.ToUint64()) should.True(any.ToBool()) should.Equal(`{"Field1":"hello"}`, any.ToString()) // cannot pass! //stream := NewStream(ConfigDefault, nil, 32) //any.WriteTo(stream) //should.Equal(`{"Field1":"hello"}`, string(stream.Buffer())) // cannot pass! } func Test_any_within_struct(t *testing.T) { should := require.New(t) type TestObject struct { Field1 jsoniter.Any Field2 jsoniter.Any } obj := TestObject{} err := jsoniter.UnmarshalFromString(`{"Field1": "hello", "Field2": [1,2,3]}`, &obj) should.Nil(err) should.Equal("hello", obj.Field1.ToString()) should.Equal("[1,2,3]", obj.Field2.ToString()) } func Test_object_wrapper_any_get_all(t *testing.T) { should := require.New(t) type TestObject struct { Field1 []int Field2 []int } any := jsoniter.Wrap(TestObject{[]int{1, 2}, []int{3, 4}}) should.Contains(any.Get('*', 0).ToString(), `"Field2":3`) should.Contains(any.Keys(), "Field1") should.Contains(any.Keys(), "Field2") should.NotContains(any.Keys(), "Field3") } golang-github-json-iterator-go-1.1.12/any_tests/jsoniter_any_string_test.go000066400000000000000000000030751420644465700272360ustar00rootroot00000000000000package any_tests import ( "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) var stringConvertMap = map[string]string{ "null": "", "321.1": "321.1", `"1.1"`: "1.1", `"-123.1"`: "-123.1", "0.0": "0.0", "0": "0", `"0"`: "0", `"0.0"`: "0.0", `"00.0"`: "00.0", "true": "true", "false": "false", `"true"`: "true", `"false"`: "false", `"true123"`: "true123", `"+1"`: "+1", "[]": "[]", "[1,2]": "[1,2]", "{}": "{}", `{"a":1, "stream":true}`: `{"a":1, "stream":true}`, } func Test_read_any_to_string(t *testing.T) { should := require.New(t) for k, v := range stringConvertMap { any := jsoniter.Get([]byte(k)) should.Equal(v, any.ToString(), "original val "+k) } } func Test_read_string_as_any(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte(`"hello"`)) should.Equal("hello", any.ToString()) should.True(any.ToBool()) any = jsoniter.Get([]byte(`" "`)) should.False(any.ToBool()) any = jsoniter.Get([]byte(`"false"`)) should.True(any.ToBool()) any = jsoniter.Get([]byte(`"123"`)) should.Equal(123, any.ToInt()) } func Test_wrap_string(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("-32000")).MustBeValid() should.Equal(-32000, any.ToInt()) should.NoError(any.LastError()) } golang-github-json-iterator-go-1.1.12/any_tests/jsoniter_must_be_valid_test.go000066400000000000000000000036301420644465700276730ustar00rootroot00000000000000package any_tests import ( "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) // if must be valid is useless, just drop this test func Test_must_be_valid(t *testing.T) { should := require.New(t) any := jsoniter.Get([]byte("123")) should.Equal(any.MustBeValid().ToInt(), 123) any = jsoniter.Wrap(int8(10)) should.Equal(any.MustBeValid().ToInt(), 10) any = jsoniter.Wrap(int16(10)) should.Equal(any.MustBeValid().ToInt(), 10) any = jsoniter.Wrap(int32(10)) should.Equal(any.MustBeValid().ToInt(), 10) any = jsoniter.Wrap(int64(10)) should.Equal(any.MustBeValid().ToInt(), 10) any = jsoniter.Wrap(uint(10)) should.Equal(any.MustBeValid().ToInt(), 10) any = jsoniter.Wrap(uint8(10)) should.Equal(any.MustBeValid().ToInt(), 10) any = jsoniter.Wrap(uint16(10)) should.Equal(any.MustBeValid().ToInt(), 10) any = jsoniter.Wrap(uint32(10)) should.Equal(any.MustBeValid().ToInt(), 10) any = jsoniter.Wrap(uint64(10)) should.Equal(any.MustBeValid().ToInt(), 10) any = jsoniter.Wrap(float32(10)) should.Equal(any.MustBeValid().ToFloat64(), float64(10)) any = jsoniter.Wrap(float64(10)) should.Equal(any.MustBeValid().ToFloat64(), float64(10)) any = jsoniter.Wrap(true) should.Equal(any.MustBeValid().ToFloat64(), float64(1)) any = jsoniter.Wrap(false) should.Equal(any.MustBeValid().ToFloat64(), float64(0)) any = jsoniter.Wrap(nil) should.Equal(any.MustBeValid().ToFloat64(), float64(0)) any = jsoniter.Wrap(struct{ age int }{age: 1}) should.Equal(any.MustBeValid().ToFloat64(), float64(0)) any = jsoniter.Wrap(map[string]interface{}{"abc": 1}) should.Equal(any.MustBeValid().ToFloat64(), float64(0)) any = jsoniter.Wrap("abc") should.Equal(any.MustBeValid().ToFloat64(), float64(0)) any = jsoniter.Wrap([]int{}) should.Equal(any.MustBeValid().ToFloat64(), float64(0)) any = jsoniter.Wrap([]int{1, 2}) should.Equal(any.MustBeValid().ToFloat64(), float64(1)) } golang-github-json-iterator-go-1.1.12/any_tests/jsoniter_wrap_test.go000066400000000000000000000066651420644465700260420ustar00rootroot00000000000000package any_tests import ( "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_wrap_and_valuetype_everything(t *testing.T) { should := require.New(t) var i interface{} any := jsoniter.Get([]byte("123")) // default of number type is float64 i = float64(123) should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(int8(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) // get interface is not int8 interface // i = int8(10) // should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(int16(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) //i = int16(10) //should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(int32(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) i = int32(10) should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(int64(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) i = int64(10) should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(uint(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) // not equal //i = uint(10) //should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(uint8(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) // not equal // i = uint8(10) // should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(uint16(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) any = jsoniter.Wrap(uint32(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) i = uint32(10) should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(uint64(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) i = uint64(10) should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(float32(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) // not equal //i = float32(10) //should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(float64(10)) should.Equal(any.ValueType(), jsoniter.NumberValue) should.Equal(any.LastError(), nil) i = float64(10) should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(true) should.Equal(any.ValueType(), jsoniter.BoolValue) should.Equal(any.LastError(), nil) i = true should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(false) should.Equal(any.ValueType(), jsoniter.BoolValue) should.Equal(any.LastError(), nil) i = false should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(nil) should.Equal(any.ValueType(), jsoniter.NilValue) should.Equal(any.LastError(), nil) i = nil should.Equal(i, any.GetInterface()) stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 32) any.WriteTo(stream) should.Equal("null", string(stream.Buffer())) should.Equal(any.LastError(), nil) any = jsoniter.Wrap(struct{ age int }{age: 1}) should.Equal(any.ValueType(), jsoniter.ObjectValue) should.Equal(any.LastError(), nil) i = struct{ age int }{age: 1} should.Equal(i, any.GetInterface()) any = jsoniter.Wrap(map[string]interface{}{"abc": 1}) should.Equal(any.ValueType(), jsoniter.ObjectValue) should.Equal(any.LastError(), nil) i = map[string]interface{}{"abc": 1} should.Equal(i, any.GetInterface()) any = jsoniter.Wrap("abc") i = "abc" should.Equal(i, any.GetInterface()) should.Equal(nil, any.LastError()) } golang-github-json-iterator-go-1.1.12/any_uint32.go000066400000000000000000000022101420644465700220550ustar00rootroot00000000000000package jsoniter import ( "strconv" ) type uint32Any struct { baseAny val uint32 } func (any *uint32Any) LastError() error { return nil } func (any *uint32Any) ValueType() ValueType { return NumberValue } func (any *uint32Any) MustBeValid() Any { return any } func (any *uint32Any) ToBool() bool { return any.val != 0 } func (any *uint32Any) ToInt() int { return int(any.val) } func (any *uint32Any) ToInt32() int32 { return int32(any.val) } func (any *uint32Any) ToInt64() int64 { return int64(any.val) } func (any *uint32Any) ToUint() uint { return uint(any.val) } func (any *uint32Any) ToUint32() uint32 { return any.val } func (any *uint32Any) ToUint64() uint64 { return uint64(any.val) } func (any *uint32Any) ToFloat32() float32 { return float32(any.val) } func (any *uint32Any) ToFloat64() float64 { return float64(any.val) } func (any *uint32Any) ToString() string { return strconv.FormatInt(int64(any.val), 10) } func (any *uint32Any) WriteTo(stream *Stream) { stream.WriteUint32(any.val) } func (any *uint32Any) Parse() *Iterator { return nil } func (any *uint32Any) GetInterface() interface{} { return any.val } golang-github-json-iterator-go-1.1.12/any_uint64.go000066400000000000000000000022021420644465700220630ustar00rootroot00000000000000package jsoniter import ( "strconv" ) type uint64Any struct { baseAny val uint64 } func (any *uint64Any) LastError() error { return nil } func (any *uint64Any) ValueType() ValueType { return NumberValue } func (any *uint64Any) MustBeValid() Any { return any } func (any *uint64Any) ToBool() bool { return any.val != 0 } func (any *uint64Any) ToInt() int { return int(any.val) } func (any *uint64Any) ToInt32() int32 { return int32(any.val) } func (any *uint64Any) ToInt64() int64 { return int64(any.val) } func (any *uint64Any) ToUint() uint { return uint(any.val) } func (any *uint64Any) ToUint32() uint32 { return uint32(any.val) } func (any *uint64Any) ToUint64() uint64 { return any.val } func (any *uint64Any) ToFloat32() float32 { return float32(any.val) } func (any *uint64Any) ToFloat64() float64 { return float64(any.val) } func (any *uint64Any) ToString() string { return strconv.FormatUint(any.val, 10) } func (any *uint64Any) WriteTo(stream *Stream) { stream.WriteUint64(any.val) } func (any *uint64Any) Parse() *Iterator { return nil } func (any *uint64Any) GetInterface() interface{} { return any.val } golang-github-json-iterator-go-1.1.12/api_tests/000077500000000000000000000000001420644465700215335ustar00rootroot00000000000000golang-github-json-iterator-go-1.1.12/api_tests/config_test.go000066400000000000000000000125311420644465700243700ustar00rootroot00000000000000package test import ( "encoding/json" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_use_number_for_unmarshal(t *testing.T) { should := require.New(t) api := jsoniter.Config{UseNumber: true}.Froze() var obj interface{} should.Nil(api.UnmarshalFromString("123", &obj)) should.Equal(json.Number("123"), obj) } func Test_customize_float_marshal(t *testing.T) { should := require.New(t) json := jsoniter.Config{MarshalFloatWith6Digits: true}.Froze() str, err := json.MarshalToString(float32(1.23456789)) should.Nil(err) should.Equal("1.234568", str) } func Test_customize_tag_key(t *testing.T) { type TestObject struct { Field string `orm:"field"` } should := require.New(t) json := jsoniter.Config{TagKey: "orm"}.Froze() str, err := json.MarshalToString(TestObject{"hello"}) should.Nil(err) should.Equal(`{"field":"hello"}`, str) } func Test_read_large_number_as_interface(t *testing.T) { should := require.New(t) var val interface{} err := jsoniter.Config{UseNumber: true}.Froze().UnmarshalFromString(`123456789123456789123456789`, &val) should.Nil(err) output, err := jsoniter.MarshalToString(val) should.Nil(err) should.Equal(`123456789123456789123456789`, output) } type caseSensitiveStruct struct { A string `json:"a"` B string `json:"b,omitempty"` C *C `json:"C,omitempty"` } type C struct { D int64 `json:"D,omitempty"` E *E `json:"e,omitempty"` } type E struct { F string `json:"F,omitempty"` } func Test_CaseSensitive(t *testing.T) { should := require.New(t) testCases := []struct { input string expectedOutput string caseSensitive bool }{ { input: `{"A":"foo","B":"bar"}`, expectedOutput: `{"a":"foo","b":"bar"}`, caseSensitive: false, }, { input: `{"a":"foo","b":"bar"}`, expectedOutput: `{"a":"foo","b":"bar"}`, caseSensitive: true, }, { input: `{"a":"foo","b":"bar","C":{"D":10}}`, expectedOutput: `{"a":"foo","b":"bar","C":{"D":10}}`, caseSensitive: true, }, { input: `{"a":"foo","B":"bar","c":{"d":10}}`, expectedOutput: `{"a":"foo"}`, caseSensitive: true, }, { input: `{"a":"foo","C":{"d":10}}`, expectedOutput: `{"a":"foo","C":{}}`, caseSensitive: true, }, { input: `{"a":"foo","C":{"D":10,"e":{"f":"baz"}}}`, expectedOutput: `{"a":"foo","C":{"D":10,"e":{}}}`, caseSensitive: true, }, { input: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`, expectedOutput: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`, caseSensitive: true, }, { input: `{"A":"foo","c":{"d":10,"E":{"f":"baz"}}}`, expectedOutput: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`, caseSensitive: false, }, } for _, tc := range testCases { val := caseSensitiveStruct{} err := jsoniter.Config{CaseSensitive: tc.caseSensitive}.Froze().UnmarshalFromString(tc.input, &val) should.Nil(err) output, err := jsoniter.MarshalToString(val) should.Nil(err) should.Equal(tc.expectedOutput, output) } } type structWithElevenFields struct { A string `json:"A,omitempty"` B string `json:"B,omitempty"` C string `json:"C,omitempty"` D string `json:"d,omitempty"` E string `json:"e,omitempty"` F string `json:"f,omitempty"` G string `json:"g,omitempty"` H string `json:"h,omitempty"` I string `json:"i,omitempty"` J string `json:"j,omitempty"` K string `json:"k,omitempty"` } func Test_CaseSensitive_MoreThanTenFields(t *testing.T) { should := require.New(t) testCases := []struct { input string expectedOutput string caseSensitive bool }{ { input: `{"A":"1","B":"2","C":"3","d":"4","e":"5","f":"6","g":"7","h":"8","i":"9","j":"10","k":"11"}`, expectedOutput: `{"A":"1","B":"2","C":"3","d":"4","e":"5","f":"6","g":"7","h":"8","i":"9","j":"10","k":"11"}`, caseSensitive: true, }, { input: `{"a":"1","b":"2","c":"3","D":"4","E":"5","F":"6"}`, expectedOutput: `{"A":"1","B":"2","C":"3","d":"4","e":"5","f":"6"}`, caseSensitive: false, }, { input: `{"A":"1","b":"2","d":"4","E":"5"}`, expectedOutput: `{"A":"1","d":"4"}`, caseSensitive: true, }, } for _, tc := range testCases { val := structWithElevenFields{} err := jsoniter.Config{CaseSensitive: tc.caseSensitive}.Froze().UnmarshalFromString(tc.input, &val) should.Nil(err) output, err := jsoniter.MarshalToString(val) should.Nil(err) should.Equal(tc.expectedOutput, output) } } type onlyTaggedFieldStruct struct { A string `json:"a"` B string FSimpl F `json:"f_simpl"` ISimpl I FPtr *F `json:"f_ptr"` IPtr *I F *I } type F struct { G string `json:"g"` H string } type I struct { J string `json:"j"` K string } func Test_OnlyTaggedField(t *testing.T) { should := require.New(t) obj := onlyTaggedFieldStruct{ A: "a", B: "b", FSimpl: F{G: "g", H: "h"}, ISimpl: I{J: "j", K: "k"}, FPtr: &F{G: "g", H: "h"}, IPtr: &I{J: "j", K: "k"}, F: F{G: "g", H: "h"}, I: &I{J: "j", K: "k"}, } output, err := jsoniter.Config{OnlyTaggedField: true}.Froze().Marshal(obj) should.Nil(err) m := make(map[string]interface{}) err = jsoniter.Unmarshal(output, &m) should.Nil(err) should.Equal(map[string]interface{}{ "a": "a", "f_simpl": map[string]interface{}{ "g": "g", }, "f_ptr": map[string]interface{}{ "g": "g", }, "g": "g", "j": "j", }, m) } golang-github-json-iterator-go-1.1.12/api_tests/decoder_test.go000066400000000000000000000034041420644465700245270ustar00rootroot00000000000000package test import ( "bytes" "encoding/json" "github.com/json-iterator/go" "github.com/stretchr/testify/require" "io/ioutil" "testing" ) func Test_disallowUnknownFields(t *testing.T) { should := require.New(t) type TestObject struct{} var obj TestObject decoder := jsoniter.NewDecoder(bytes.NewBufferString(`{"field1":100}`)) decoder.DisallowUnknownFields() should.Error(decoder.Decode(&obj)) } func Test_new_decoder(t *testing.T) { should := require.New(t) decoder1 := json.NewDecoder(bytes.NewBufferString(`[1][2]`)) decoder2 := jsoniter.NewDecoder(bytes.NewBufferString(`[1][2]`)) arr1 := []int{} should.Nil(decoder1.Decode(&arr1)) should.Equal([]int{1}, arr1) arr2 := []int{} should.True(decoder1.More()) buffered, _ := ioutil.ReadAll(decoder1.Buffered()) should.Equal("[2]", string(buffered)) should.Nil(decoder2.Decode(&arr2)) should.Equal([]int{1}, arr2) should.True(decoder2.More()) buffered, _ = ioutil.ReadAll(decoder2.Buffered()) should.Equal("[2]", string(buffered)) should.Nil(decoder1.Decode(&arr1)) should.Equal([]int{2}, arr1) should.False(decoder1.More()) should.Nil(decoder2.Decode(&arr2)) should.Equal([]int{2}, arr2) should.False(decoder2.More()) } func Test_use_number(t *testing.T) { should := require.New(t) decoder1 := json.NewDecoder(bytes.NewBufferString(`123`)) decoder1.UseNumber() decoder2 := jsoniter.NewDecoder(bytes.NewBufferString(`123`)) decoder2.UseNumber() var obj1 interface{} should.Nil(decoder1.Decode(&obj1)) should.Equal(json.Number("123"), obj1) var obj2 interface{} should.Nil(decoder2.Decode(&obj2)) should.Equal(json.Number("123"), obj2) } func Test_decoder_more(t *testing.T) { should := require.New(t) decoder := jsoniter.NewDecoder(bytes.NewBufferString("abcde")) should.True(decoder.More()) } golang-github-json-iterator-go-1.1.12/api_tests/encoder_18_test.go000066400000000000000000000021641420644465700250530ustar00rootroot00000000000000//+build go1.8 package test import ( "bytes" "encoding/json" "testing" "unicode/utf8" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_new_encoder(t *testing.T) { should := require.New(t) buf1 := &bytes.Buffer{} encoder1 := json.NewEncoder(buf1) encoder1.SetEscapeHTML(false) encoder1.Encode([]int{1}) should.Equal("[1]\n", buf1.String()) buf2 := &bytes.Buffer{} encoder2 := jsoniter.NewEncoder(buf2) encoder2.SetEscapeHTML(false) encoder2.Encode([]int{1}) should.Equal("[1]\n", buf2.String()) } func Test_string_encode_with_std_without_html_escape(t *testing.T) { api := jsoniter.Config{EscapeHTML: false}.Froze() should := require.New(t) for i := 0; i < utf8.RuneSelf; i++ { input := string([]byte{byte(i)}) buf := &bytes.Buffer{} encoder := json.NewEncoder(buf) encoder.SetEscapeHTML(false) err := encoder.Encode(input) should.Nil(err) stdOutput := buf.String() stdOutput = stdOutput[:len(stdOutput)-1] jsoniterOutputBytes, err := api.Marshal(input) should.Nil(err) jsoniterOutput := string(jsoniterOutputBytes) should.Equal(stdOutput, jsoniterOutput) } } golang-github-json-iterator-go-1.1.12/api_tests/encoder_test.go000066400000000000000000000007221420644465700245410ustar00rootroot00000000000000package test import ( "bytes" "encoding/json" "github.com/json-iterator/go" "github.com/stretchr/testify/require" "testing" ) // Standard Encoder has trailing newline. func TestEncoderHasTrailingNewline(t *testing.T) { should := require.New(t) var buf, stdbuf bytes.Buffer enc := jsoniter.ConfigCompatibleWithStandardLibrary.NewEncoder(&buf) enc.Encode(1) stdenc := json.NewEncoder(&stdbuf) stdenc.Encode(1) should.Equal(stdbuf.Bytes(), buf.Bytes()) } golang-github-json-iterator-go-1.1.12/api_tests/marshal_indent_test.go000066400000000000000000000020541420644465700261120ustar00rootroot00000000000000package test import ( "encoding/json" "github.com/json-iterator/go" "github.com/stretchr/testify/require" "testing" ) func Test_marshal_indent(t *testing.T) { should := require.New(t) obj := struct { F1 int F2 []int }{1, []int{2, 3, 4}} output, err := json.MarshalIndent(obj, "", " ") should.Nil(err) should.Equal("{\n \"F1\": 1,\n \"F2\": [\n 2,\n 3,\n 4\n ]\n}", string(output)) output, err = jsoniter.MarshalIndent(obj, "", " ") should.Nil(err) should.Equal("{\n \"F1\": 1,\n \"F2\": [\n 2,\n 3,\n 4\n ]\n}", string(output)) } func Test_marshal_indent_map(t *testing.T) { should := require.New(t) obj := map[int]int{1: 2} output, err := json.MarshalIndent(obj, "", " ") should.Nil(err) should.Equal("{\n \"1\": 2\n}", string(output)) output, err = jsoniter.MarshalIndent(obj, "", " ") should.Nil(err) should.Equal("{\n \"1\": 2\n}", string(output)) output, err = jsoniter.ConfigCompatibleWithStandardLibrary.MarshalIndent(obj, "", " ") should.Nil(err) should.Equal("{\n \"1\": 2\n}", string(output)) } golang-github-json-iterator-go-1.1.12/api_tests/marshal_json_escape_test.go000066400000000000000000000016261420644465700271260ustar00rootroot00000000000000package test import ( "bytes" "encoding/json" "testing" jsoniter "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) var marshalConfig = jsoniter.Config{ EscapeHTML: false, SortMapKeys: true, ValidateJsonRawMessage: true, }.Froze() type Container struct { Bar interface{} } func (c *Container) MarshalJSON() ([]byte, error) { return marshalConfig.Marshal(&c.Bar) } func TestEncodeEscape(t *testing.T) { should := require.New(t) container := &Container{ Bar: []string{"123", "ooo"}, } out, err := marshalConfig.Marshal(container) should.Nil(err) bufout := string(out) var stdbuf bytes.Buffer stdenc := json.NewEncoder(&stdbuf) stdenc.SetEscapeHTML(false) err = stdenc.Encode(container) should.Nil(err) stdout := string(stdbuf.Bytes()) if stdout[len(stdout)-1:] == "\n" { stdout = stdout[:len(stdout)-1] } should.Equal(stdout, bufout) } golang-github-json-iterator-go-1.1.12/api_tests/marshal_json_test.go000066400000000000000000000012371420644465700256040ustar00rootroot00000000000000package test import ( "bytes" "encoding/json" "github.com/json-iterator/go" "testing" "github.com/stretchr/testify/require" ) type Foo struct { Bar interface{} } func (f Foo) MarshalJSON() ([]byte, error) { var buf bytes.Buffer err := json.NewEncoder(&buf).Encode(f.Bar) return buf.Bytes(), err } // Standard Encoder has trailing newline. func TestEncodeMarshalJSON(t *testing.T) { foo := Foo { Bar: 123, } should := require.New(t) var buf, stdbuf bytes.Buffer enc := jsoniter.ConfigCompatibleWithStandardLibrary.NewEncoder(&buf) enc.Encode(foo) stdenc := json.NewEncoder(&stdbuf) stdenc.Encode(foo) should.Equal(stdbuf.Bytes(), buf.Bytes()) } golang-github-json-iterator-go-1.1.12/benchmarks/000077500000000000000000000000001420644465700216555ustar00rootroot00000000000000golang-github-json-iterator-go-1.1.12/benchmarks/encode_string_test.go000066400000000000000000000007171420644465700260730ustar00rootroot00000000000000package test import ( "bytes" "github.com/json-iterator/go" "testing" ) func Benchmark_encode_string_with_SetEscapeHTML(b *testing.B) { type V struct { S string B bool I int } var json = jsoniter.ConfigCompatibleWithStandardLibrary b.ReportAllocs() for i := 0; i < b.N; i++ { buf := &bytes.Buffer{} enc := json.NewEncoder(buf) enc.SetEscapeHTML(true) if err := enc.Encode(V{S: "s", B: true, I: 233}); err != nil { b.Fatal(err) } } } golang-github-json-iterator-go-1.1.12/benchmarks/jsoniter_large_file_test.go000066400000000000000000000071531420644465700272570ustar00rootroot00000000000000package test import ( "encoding/json" "github.com/json-iterator/go" "io/ioutil" "os" "testing" ) //func Test_large_file(t *testing.T) { // file, err := os.Open("/tmp/large-file.json") // if err != nil { // t.Fatal(err) // } // iter := Parse(file, 4096) // count := 0 // for iter.ReadArray() { // iter.Skip() // count++ // } // if count != 11351 { // t.Fatal(count) // } //} func init() { ioutil.WriteFile("/tmp/large-file.json", []byte(`[{ "person": { "id": "d50887ca-a6ce-4e59-b89f-14f0b5d03b03", "name": { "fullName": "Leonid Bugaev", "givenName": "Leonid", "familyName": "Bugaev" }, "email": "leonsbox@gmail.com", "gender": "male", "location": "Saint Petersburg, Saint Petersburg, RU", "geo": { "city": "Saint Petersburg", "state": "Saint Petersburg", "country": "Russia", "lat": 59.9342802, "lng": 30.3350986 }, "bio": "Senior engineer at Granify.com", "site": "http://flickfaver.com", "avatar": "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/d50887ca-a6ce-4e59-b89f-14f0b5d03b03", "employment": { "name": "www.latera.ru", "title": "Software Engineer", "domain": "gmail.com" }, "facebook": { "handle": "leonid.bugaev" }, "github": { "handle": "buger", "id": 14009, "avatar": "https://avatars.githubusercontent.com/u/14009?v=3", "company": "Granify", "blog": "http://leonsbox.com", "followers": 95, "following": 10 }, "twitter": { "handle": "flickfaver", "id": 77004410, "bio": null, "followers": 2, "following": 1, "statuses": 5, "favorites": 0, "location": "", "site": "http://flickfaver.com", "avatar": null }, "linkedin": { "handle": "in/leonidbugaev" }, "googleplus": { "handle": null }, "angellist": { "handle": "leonid-bugaev", "id": 61541, "bio": "Senior engineer at Granify.com", "blog": "http://buger.github.com", "site": "http://buger.github.com", "followers": 41, "avatar": "https://d1qb2nb5cznatu.cloudfront.net/users/61541-medium_jpg?1405474390" }, "klout": { "handle": null, "score": null }, "foursquare": { "handle": null }, "aboutme": { "handle": "leonid.bugaev", "bio": null, "avatar": null }, "gravatar": { "handle": "buger", "urls": [ ], "avatar": "http://1.gravatar.com/avatar/f7c8edd577d13b8930d5522f28123510", "avatars": [ { "url": "http://1.gravatar.com/avatar/f7c8edd577d13b8930d5522f28123510", "type": "thumbnail" } ] }, "fuzzy": false }, "company": "hello" }]`), 0666) } /* 200000 8886 ns/op 4336 B/op 6 allocs/op 50000 34244 ns/op 6744 B/op 14 allocs/op */ func Benchmark_jsoniter_large_file(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { file, _ := os.Open("/tmp/large-file.json") iter := jsoniter.Parse(jsoniter.ConfigDefault, file, 4096) count := 0 iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool { // Skip() is strict by default, use --tags jsoniter-sloppy to skip without validation iter.Skip() count++ return true }) file.Close() if iter.Error != nil { b.Error(iter.Error) } } } func Benchmark_json_large_file(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { file, _ := os.Open("/tmp/large-file.json") bytes, _ := ioutil.ReadAll(file) file.Close() result := []struct{}{} err := json.Unmarshal(bytes, &result) if err != nil { b.Error(err) } } } golang-github-json-iterator-go-1.1.12/benchmarks/stream_test.go000066400000000000000000000150371420644465700245440ustar00rootroot00000000000000package test import ( "bytes" "strconv" "testing" jsoniter "github.com/json-iterator/go" ) func Benchmark_stream_encode_big_object(b *testing.B) { var buf bytes.Buffer var stream = jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 100) for i := 0; i < b.N; i++ { buf.Reset() stream.Reset(&buf) encodeObject(stream) if stream.Error != nil { b.Errorf("error: %+v", stream.Error) } } } func TestEncodeObject(t *testing.T) { var stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 100) encodeObject(stream) if stream.Error != nil { t.Errorf("error encoding a test object: %+v", stream.Error) return } var m = make(map[string]interface{}) if err := jsoniter.Unmarshal(stream.Buffer(), &m); err != nil { t.Errorf("error unmarshaling a test object: %+v", err) return } } func encodeObject(stream *jsoniter.Stream) { stream.WriteObjectStart() stream.WriteObjectField("objectId") stream.WriteUint64(8838243212) stream.WriteMore() stream.WriteObjectField("name") stream.WriteString("Jane Doe") stream.WriteMore() stream.WriteObjectField("address") stream.WriteObjectStart() for i, field := range addressFields { if i != 0 { stream.WriteMore() } stream.WriteObjectField(field.key) stream.WriteString(field.val) } stream.WriteMore() stream.WriteObjectField("geo") { stream.WriteObjectStart() stream.WriteObjectField("latitude") stream.WriteFloat64(-154.550817) stream.WriteMore() stream.WriteObjectField("longitude") stream.WriteFloat64(-84.176159) stream.WriteObjectEnd() } stream.WriteObjectEnd() stream.WriteMore() stream.WriteObjectField("specialties") stream.WriteArrayStart() for i, s := range specialties { if i != 0 { stream.WriteMore() } stream.WriteString(s) } stream.WriteArrayEnd() stream.WriteMore() for i, text := range longText { if i != 0 { stream.WriteMore() } stream.WriteObjectField("longText" + strconv.Itoa(i)) stream.WriteString(text) } for i := 0; i < 25; i++ { num := i * 18328 stream.WriteMore() stream.WriteObjectField("integerField" + strconv.Itoa(i)) stream.WriteInt64(int64(num)) } stream.WriteObjectEnd() } type field struct{ key, val string } var ( addressFields = []field{ {"address1", "123 Example St"}, {"address2", "Apartment 5D, Suite 3"}, {"city", "Miami"}, {"state", "FL"}, {"postalCode", "33133"}, {"country", "US"}, } specialties = []string{ "Web Design", "Go Programming", "Tennis", "Cycling", "Mixed martial arts", } longText = []string{ `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`, `Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?`, `But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?`, `At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.`, `On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains.`, } ) golang-github-json-iterator-go-1.1.12/build.sh000077500000000000000000000005751420644465700212050ustar00rootroot00000000000000#!/bin/bash set -e set -x if [ ! -d /tmp/build-golang/src/github.com/json-iterator ]; then mkdir -p /tmp/build-golang/src/github.com/json-iterator ln -s $PWD /tmp/build-golang/src/github.com/json-iterator/go fi export GOPATH=/tmp/build-golang go get -u github.com/golang/dep/cmd/dep cd /tmp/build-golang/src/github.com/json-iterator/go exec $GOPATH/bin/dep ensure -update golang-github-json-iterator-go-1.1.12/config.go000066400000000000000000000244611420644465700213430ustar00rootroot00000000000000package 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)) defer cfg.ReturnIterator(iter) iter.Read() if iter.Error != nil && iter.Error != io.EOF { stream.WriteRaw("null") } else { 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 } golang-github-json-iterator-go-1.1.12/example_test.go000066400000000000000000000051031420644465700225600ustar00rootroot00000000000000package jsoniter import ( "fmt" "os" "strings" ) func ExampleMarshal() { type ColorGroup struct { ID int Name string Colors []string } group := ColorGroup{ ID: 1, Name: "Reds", Colors: []string{"Crimson", "Red", "Ruby", "Maroon"}, } b, err := Marshal(group) if err != nil { fmt.Println("error:", err) } os.Stdout.Write(b) // Output: // {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]} } func ExampleUnmarshal() { var jsonBlob = []byte(`[ {"Name": "Platypus", "Order": "Monotremata"}, {"Name": "Quoll", "Order": "Dasyuromorphia"} ]`) type Animal struct { Name string Order string } var animals []Animal err := Unmarshal(jsonBlob, &animals) if err != nil { fmt.Println("error:", err) } fmt.Printf("%+v", animals) // Output: // [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}] } func ExampleConfigFastest_Marshal() { type ColorGroup struct { ID int Name string Colors []string } group := ColorGroup{ ID: 1, Name: "Reds", Colors: []string{"Crimson", "Red", "Ruby", "Maroon"}, } stream := ConfigFastest.BorrowStream(nil) defer ConfigFastest.ReturnStream(stream) stream.WriteVal(group) if stream.Error != nil { fmt.Println("error:", stream.Error) } os.Stdout.Write(stream.Buffer()) // Output: // {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]} } func ExampleConfigFastest_Unmarshal() { var jsonBlob = []byte(`[ {"Name": "Platypus", "Order": "Monotremata"}, {"Name": "Quoll", "Order": "Dasyuromorphia"} ]`) type Animal struct { Name string Order string } var animals []Animal iter := ConfigFastest.BorrowIterator(jsonBlob) defer ConfigFastest.ReturnIterator(iter) iter.ReadVal(&animals) if iter.Error != nil { fmt.Println("error:", iter.Error) } fmt.Printf("%+v", animals) // Output: // [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}] } func ExampleGet() { val := []byte(`{"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}`) fmt.Printf(Get(val, "Colors", 0).ToString()) // Output: // Crimson } func ExampleMyKey() { hello := MyKey("hello") output, _ := Marshal(map[*MyKey]string{&hello: "world"}) fmt.Println(string(output)) obj := map[*MyKey]string{} Unmarshal(output, &obj) for k, v := range obj { fmt.Println(*k, v) } // Output: // {"Hello":"world"} // Hel world } type MyKey string func (m *MyKey) MarshalText() ([]byte, error) { return []byte(strings.Replace(string(*m), "h", "H", -1)), nil } func (m *MyKey) UnmarshalText(text []byte) error { *m = MyKey(text[:3]) return nil } golang-github-json-iterator-go-1.1.12/extension_tests/000077500000000000000000000000001420644465700227765ustar00rootroot00000000000000golang-github-json-iterator-go-1.1.12/extension_tests/decoder_test.go000066400000000000000000000117671420644465700260050ustar00rootroot00000000000000package test import ( "bytes" "fmt" "github.com/json-iterator/go" "github.com/stretchr/testify/require" "strconv" "testing" "time" "unsafe" ) func Test_customize_type_decoder(t *testing.T) { t.Skip() jsoniter.RegisterTypeDecoderFunc("time.Time", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) { t, err := time.ParseInLocation("2006-01-02 15:04:05", iter.ReadString(), time.UTC) if err != nil { iter.Error = err return } *((*time.Time)(ptr)) = t }) //defer jsoniter.ConfigDefault.(*frozenConfig).cleanDecoders() val := time.Time{} err := jsoniter.Unmarshal([]byte(`"2016-12-05 08:43:28"`), &val) if err != nil { t.Fatal(err) } year, month, day := val.Date() if year != 2016 || month != 12 || day != 5 { t.Fatal(val) } } func Test_customize_byte_array_encoder(t *testing.T) { t.Skip() //jsoniter.ConfigDefault.(*frozenConfig).cleanEncoders() should := require.New(t) jsoniter.RegisterTypeEncoderFunc("[]uint8", func(ptr unsafe.Pointer, stream *jsoniter.Stream) { t := *((*[]byte)(ptr)) stream.WriteString(string(t)) }, nil) //defer jsoniter.ConfigDefault.(*frozenConfig).cleanEncoders() val := []byte("abc") str, err := jsoniter.MarshalToString(val) should.Nil(err) should.Equal(`"abc"`, str) } type CustomEncoderAttachmentTestStruct struct { Value int32 `json:"value"` } type CustomEncoderAttachmentTestStructEncoder struct {} func (c *CustomEncoderAttachmentTestStructEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) { attachVal, ok := stream.Attachment.(int) stream.WriteRaw(`"`) stream.WriteRaw(fmt.Sprintf("%t %d", ok, attachVal)) stream.WriteRaw(`"`) } func (c *CustomEncoderAttachmentTestStructEncoder) IsEmpty(ptr unsafe.Pointer) bool { return false } func Test_custom_encoder_attachment(t *testing.T) { jsoniter.RegisterTypeEncoder("test.CustomEncoderAttachmentTestStruct", &CustomEncoderAttachmentTestStructEncoder{}) expectedValue := 17 should := require.New(t) buf := &bytes.Buffer{} stream := jsoniter.NewStream(jsoniter.Config{SortMapKeys: true}.Froze(), buf, 4096) stream.Attachment = expectedValue val := map[string]CustomEncoderAttachmentTestStruct{"a": {}} stream.WriteVal(val) stream.Flush() should.Nil(stream.Error) should.Equal("{\"a\":\"true 17\"}", buf.String()) } func Test_customize_field_decoder(t *testing.T) { type Tom struct { field1 string } jsoniter.RegisterFieldDecoderFunc("jsoniter.Tom", "field1", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) { *((*string)(ptr)) = strconv.Itoa(iter.ReadInt()) }) //defer jsoniter.ConfigDefault.(*frozenConfig).cleanDecoders() tom := Tom{} err := jsoniter.Unmarshal([]byte(`{"field1": 100}`), &tom) if err != nil { t.Fatal(err) } } func Test_recursive_empty_interface_customization(t *testing.T) { t.Skip() var obj interface{} jsoniter.RegisterTypeDecoderFunc("interface {}", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) { switch iter.WhatIsNext() { case jsoniter.NumberValue: *(*interface{})(ptr) = iter.ReadInt64() default: *(*interface{})(ptr) = iter.Read() } }) should := require.New(t) jsoniter.Unmarshal([]byte("[100]"), &obj) should.Equal([]interface{}{int64(100)}, obj) } type MyInterface interface { Hello() string } type MyString string func (ms MyString) Hello() string { return string(ms) } func Test_read_custom_interface(t *testing.T) { t.Skip() should := require.New(t) var val MyInterface jsoniter.RegisterTypeDecoderFunc("jsoniter.MyInterface", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) { *((*MyInterface)(ptr)) = MyString(iter.ReadString()) }) err := jsoniter.UnmarshalFromString(`"hello"`, &val) should.Nil(err) should.Equal("hello", val.Hello()) } const flow1 = ` {"A":"hello"} {"A":"hello"} {"A":"hello"} {"A":"hello"} {"A":"hello"}` const flow2 = ` {"A":"hello"} {"A":"hello"} {"A":"hello"} {"A":"hello"} {"A":"hello"} ` type ( Type1 struct { A string } Type2 struct { A string } ) func (t *Type2) UnmarshalJSON(data []byte) error { return nil } func (t *Type2) MarshalJSON() ([]byte, error) { return nil, nil } func TestType1NoFinalLF(t *testing.T) { reader := bytes.NewReader([]byte(flow1)) dec := jsoniter.NewDecoder(reader) i := 0 for dec.More() { data := &Type1{} if err := dec.Decode(data); err != nil { t.Errorf("at %v got %v", i, err) } i++ } } func TestType1FinalLF(t *testing.T) { reader := bytes.NewReader([]byte(flow2)) dec := jsoniter.NewDecoder(reader) i := 0 for dec.More() { data := &Type1{} if err := dec.Decode(data); err != nil { t.Errorf("at %v got %v", i, err) } i++ } } func TestType2NoFinalLF(t *testing.T) { reader := bytes.NewReader([]byte(flow1)) dec := jsoniter.NewDecoder(reader) i := 0 for dec.More() { data := &Type2{} if err := dec.Decode(data); err != nil { t.Errorf("at %v got %v", i, err) } i++ } } func TestType2FinalLF(t *testing.T) { reader := bytes.NewReader([]byte(flow2)) dec := jsoniter.NewDecoder(reader) i := 0 for dec.More() { data := &Type2{} if err := dec.Decode(data); err != nil { t.Errorf("at %v got %v", i, err) } i++ } } golang-github-json-iterator-go-1.1.12/extension_tests/extension_test.go000066400000000000000000000056511420644465700264070ustar00rootroot00000000000000package test import ( "github.com/json-iterator/go" "github.com/modern-go/reflect2" "github.com/stretchr/testify/require" "reflect" "strconv" "testing" "unsafe" ) type TestObject1 struct { Field1 string } type testExtension struct { jsoniter.DummyExtension } func (extension *testExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) { if structDescriptor.Type.String() != "test.TestObject1" { return } binding := structDescriptor.GetField("Field1") binding.Encoder = &funcEncoder{fun: func(ptr unsafe.Pointer, stream *jsoniter.Stream) { str := *((*string)(ptr)) val, _ := strconv.Atoi(str) stream.WriteInt(val) }} binding.Decoder = &funcDecoder{func(ptr unsafe.Pointer, iter *jsoniter.Iterator) { *((*string)(ptr)) = strconv.Itoa(iter.ReadInt()) }} binding.ToNames = []string{"field-1"} binding.FromNames = []string{"field-1"} } func Test_customize_field_by_extension(t *testing.T) { should := require.New(t) cfg := jsoniter.Config{}.Froze() cfg.RegisterExtension(&testExtension{}) obj := TestObject1{} err := cfg.UnmarshalFromString(`{"field-1": 100}`, &obj) should.Nil(err) should.Equal("100", obj.Field1) str, err := cfg.MarshalToString(obj) should.Nil(err) should.Equal(`{"field-1":100}`, str) } func Test_customize_map_key_encoder(t *testing.T) { should := require.New(t) cfg := jsoniter.Config{}.Froze() cfg.RegisterExtension(&testMapKeyExtension{}) m := map[int]int{1: 2} output, err := cfg.MarshalToString(m) should.NoError(err) should.Equal(`{"2":2}`, output) m = map[int]int{} should.NoError(cfg.UnmarshalFromString(output, &m)) should.Equal(map[int]int{1: 2}, m) } type testMapKeyExtension struct { jsoniter.DummyExtension } func (extension *testMapKeyExtension) CreateMapKeyEncoder(typ reflect2.Type) jsoniter.ValEncoder { if typ.Kind() == reflect.Int { return &funcEncoder{ fun: func(ptr unsafe.Pointer, stream *jsoniter.Stream) { stream.WriteRaw(`"`) stream.WriteInt(*(*int)(ptr) + 1) stream.WriteRaw(`"`) }, } } return nil } func (extension *testMapKeyExtension) CreateMapKeyDecoder(typ reflect2.Type) jsoniter.ValDecoder { if typ.Kind() == reflect.Int { return &funcDecoder{ fun: func(ptr unsafe.Pointer, iter *jsoniter.Iterator) { i, err := strconv.Atoi(iter.ReadString()) if err != nil { iter.ReportError("read map key", err.Error()) return } i-- *(*int)(ptr) = i }, } } return nil } type funcDecoder struct { fun jsoniter.DecoderFunc } func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { decoder.fun(ptr, iter) } type funcEncoder struct { fun jsoniter.EncoderFunc isEmptyFunc func(ptr unsafe.Pointer) bool } func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) { encoder.fun(ptr, stream) } func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { if encoder.isEmptyFunc == nil { return false } return encoder.isEmptyFunc(ptr) } golang-github-json-iterator-go-1.1.12/extra/000077500000000000000000000000001420644465700206635ustar00rootroot00000000000000golang-github-json-iterator-go-1.1.12/extra/binary_as_string_codec.go000066400000000000000000000116701420644465700257110ustar00rootroot00000000000000package extra import ( "github.com/json-iterator/go" "github.com/modern-go/reflect2" "unicode/utf8" "unsafe" ) // safeSet holds the value true if the ASCII character with the given array // position can be represented inside a JSON string without any further // escaping. // // All values are true except for the ASCII control characters (0-31), the // double quote ("), and the backslash character ("\"). var safeSet = [utf8.RuneSelf]bool{ ' ': true, '!': true, '"': false, '#': true, '$': true, '%': true, '&': true, '\'': true, '(': true, ')': true, '*': true, '+': true, ',': true, '-': true, '.': true, '/': true, '0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true, '7': true, '8': true, '9': true, ':': true, ';': true, '<': true, '=': true, '>': true, '?': true, '@': true, 'A': true, 'B': true, 'C': true, 'D': true, 'E': true, 'F': true, 'G': true, 'H': true, 'I': true, 'J': true, 'K': true, 'L': true, 'M': true, 'N': true, 'O': true, 'P': true, 'Q': true, 'R': true, 'S': true, 'T': true, 'U': true, 'V': true, 'W': true, 'X': true, 'Y': true, 'Z': true, '[': true, '\\': false, ']': true, '^': true, '_': true, '`': true, 'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true, 'g': true, 'h': true, 'i': true, 'j': true, 'k': true, 'l': true, 'm': true, 'n': true, 'o': true, 'p': true, 'q': true, 'r': true, 's': true, 't': true, 'u': true, 'v': true, 'w': true, 'x': true, 'y': true, 'z': true, '{': true, '|': true, '}': true, '~': true, '\u007f': true, } var binaryType = reflect2.TypeOfPtr((*[]byte)(nil)).Elem() type BinaryAsStringExtension struct { jsoniter.DummyExtension } func (extension *BinaryAsStringExtension) CreateEncoder(typ reflect2.Type) jsoniter.ValEncoder { if typ == binaryType { return &binaryAsStringCodec{} } return nil } func (extension *BinaryAsStringExtension) CreateDecoder(typ reflect2.Type) jsoniter.ValDecoder { if typ == binaryType { return &binaryAsStringCodec{} } return nil } type binaryAsStringCodec struct { } func (codec *binaryAsStringCodec) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { rawBytes := iter.ReadStringAsSlice() bytes := make([]byte, 0, len(rawBytes)) for i := 0; i < len(rawBytes); i++ { b := rawBytes[i] if b == '\\' { b2 := rawBytes[i+1] if b2 != '\\' { iter.ReportError("decode binary as string", `\\x is only supported escape`) return } b3 := rawBytes[i+2] if b3 != 'x' { iter.ReportError("decode binary as string", `\\x is only supported escape`) return } b4 := rawBytes[i+3] b5 := rawBytes[i+4] i += 4 b = readHex(iter, b4, b5) } bytes = append(bytes, b) } *(*[]byte)(ptr) = bytes } func (codec *binaryAsStringCodec) IsEmpty(ptr unsafe.Pointer) bool { return len(*((*[]byte)(ptr))) == 0 } func (codec *binaryAsStringCodec) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) { newBuffer := writeBytes(stream.Buffer(), *(*[]byte)(ptr)) stream.SetBuffer(newBuffer) } func readHex(iter *jsoniter.Iterator, b1, b2 byte) byte { var ret byte if b1 >= '0' && b1 <= '9' { ret = b1 - '0' } else if b1 >= 'a' && b1 <= 'f' { ret = b1 - 'a' + 10 } else { iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b1})) return 0 } ret *= 16 if b2 >= '0' && b2 <= '9' { ret += b2 - '0' } else if b2 >= 'a' && b2 <= 'f' { ret += b2 - 'a' + 10 } else { iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b2})) return 0 } return ret } var hex = "0123456789abcdef" func writeBytes(space []byte, s []byte) []byte { space = append(space, '"') // write string, the fast path, without utf8 and escape support var i int var c byte for i, c = range s { if c < utf8.RuneSelf && safeSet[c] { space = append(space, c) } else { break } } if i == len(s)-1 { space = append(space, '"') return space } return writeBytesSlowPath(space, s[i:]) } func writeBytesSlowPath(space []byte, s []byte) []byte { start := 0 // for the remaining parts, we process them char by char var i int var b byte for i, b = range s { if b >= utf8.RuneSelf { space = append(space, '\\', '\\', 'x', hex[b>>4], hex[b&0xF]) start = i + 1 continue } if safeSet[b] { continue } if start < i { space = append(space, s[start:i]...) } space = append(space, '\\', '\\', 'x', hex[b>>4], hex[b&0xF]) start = i + 1 } if start < len(s) { space = append(space, s[start:]...) } return append(space, '"') } golang-github-json-iterator-go-1.1.12/extra/binary_as_string_codec_test.go000066400000000000000000000015051420644465700267440ustar00rootroot00000000000000package extra import ( "github.com/json-iterator/go" "github.com/stretchr/testify/require" "testing" ) func init() { jsoniter.RegisterExtension(&BinaryAsStringExtension{}) } func TestBinaryAsStringCodec(t *testing.T) { t.Run("safe set", func(t *testing.T) { should := require.New(t) output, err := jsoniter.Marshal([]byte("hello")) should.NoError(err) should.Equal(`"hello"`, string(output)) var val []byte should.NoError(jsoniter.Unmarshal(output, &val)) should.Equal(`hello`, string(val)) }) t.Run("non safe set", func(t *testing.T) { should := require.New(t) output, err := jsoniter.Marshal([]byte{1, 2, 3, 23}) should.NoError(err) should.Equal(`"\\x01\\x02\\x03\\x17"`, string(output)) var val []byte should.NoError(jsoniter.Unmarshal(output, &val)) should.Equal([]byte{1, 2, 3, 23}, val) }) } golang-github-json-iterator-go-1.1.12/extra/fuzzy_decoder.go000066400000000000000000000204541420644465700240730ustar00rootroot00000000000000package extra import ( "encoding/json" "io" "math" "reflect" "strings" "unsafe" "github.com/json-iterator/go" "github.com/modern-go/reflect2" ) const maxUint = ^uint(0) const maxInt = int(maxUint >> 1) const minInt = -maxInt - 1 // RegisterFuzzyDecoders decode input from PHP with tolerance. // It will handle string/number auto conversation, and treat empty [] as empty struct. func RegisterFuzzyDecoders() { jsoniter.RegisterExtension(&tolerateEmptyArrayExtension{}) jsoniter.RegisterTypeDecoder("string", &fuzzyStringDecoder{}) jsoniter.RegisterTypeDecoder("float32", &fuzzyFloat32Decoder{}) jsoniter.RegisterTypeDecoder("float64", &fuzzyFloat64Decoder{}) jsoniter.RegisterTypeDecoder("int", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { if isFloat { val := iter.ReadFloat64() if val > float64(maxInt) || val < float64(minInt) { iter.ReportError("fuzzy decode int", "exceed range") return } *((*int)(ptr)) = int(val) } else { *((*int)(ptr)) = iter.ReadInt() } }}) jsoniter.RegisterTypeDecoder("uint", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { if isFloat { val := iter.ReadFloat64() if val > float64(maxUint) || val < 0 { iter.ReportError("fuzzy decode uint", "exceed range") return } *((*uint)(ptr)) = uint(val) } else { *((*uint)(ptr)) = iter.ReadUint() } }}) jsoniter.RegisterTypeDecoder("int8", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { if isFloat { val := iter.ReadFloat64() if val > float64(math.MaxInt8) || val < float64(math.MinInt8) { iter.ReportError("fuzzy decode int8", "exceed range") return } *((*int8)(ptr)) = int8(val) } else { *((*int8)(ptr)) = iter.ReadInt8() } }}) jsoniter.RegisterTypeDecoder("uint8", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { if isFloat { val := iter.ReadFloat64() if val > float64(math.MaxUint8) || val < 0 { iter.ReportError("fuzzy decode uint8", "exceed range") return } *((*uint8)(ptr)) = uint8(val) } else { *((*uint8)(ptr)) = iter.ReadUint8() } }}) jsoniter.RegisterTypeDecoder("int16", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { if isFloat { val := iter.ReadFloat64() if val > float64(math.MaxInt16) || val < float64(math.MinInt16) { iter.ReportError("fuzzy decode int16", "exceed range") return } *((*int16)(ptr)) = int16(val) } else { *((*int16)(ptr)) = iter.ReadInt16() } }}) jsoniter.RegisterTypeDecoder("uint16", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { if isFloat { val := iter.ReadFloat64() if val > float64(math.MaxUint16) || val < 0 { iter.ReportError("fuzzy decode uint16", "exceed range") return } *((*uint16)(ptr)) = uint16(val) } else { *((*uint16)(ptr)) = iter.ReadUint16() } }}) jsoniter.RegisterTypeDecoder("int32", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { if isFloat { val := iter.ReadFloat64() if val > float64(math.MaxInt32) || val < float64(math.MinInt32) { iter.ReportError("fuzzy decode int32", "exceed range") return } *((*int32)(ptr)) = int32(val) } else { *((*int32)(ptr)) = iter.ReadInt32() } }}) jsoniter.RegisterTypeDecoder("uint32", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { if isFloat { val := iter.ReadFloat64() if val > float64(math.MaxUint32) || val < 0 { iter.ReportError("fuzzy decode uint32", "exceed range") return } *((*uint32)(ptr)) = uint32(val) } else { *((*uint32)(ptr)) = iter.ReadUint32() } }}) jsoniter.RegisterTypeDecoder("int64", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { if isFloat { val := iter.ReadFloat64() if val > float64(math.MaxInt64) || val < float64(math.MinInt64) { iter.ReportError("fuzzy decode int64", "exceed range") return } *((*int64)(ptr)) = int64(val) } else { *((*int64)(ptr)) = iter.ReadInt64() } }}) jsoniter.RegisterTypeDecoder("uint64", &fuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { if isFloat { val := iter.ReadFloat64() if val > float64(math.MaxUint64) || val < 0 { iter.ReportError("fuzzy decode uint64", "exceed range") return } *((*uint64)(ptr)) = uint64(val) } else { *((*uint64)(ptr)) = iter.ReadUint64() } }}) } type tolerateEmptyArrayExtension struct { jsoniter.DummyExtension } func (extension *tolerateEmptyArrayExtension) DecorateDecoder(typ reflect2.Type, decoder jsoniter.ValDecoder) jsoniter.ValDecoder { if typ.Kind() == reflect.Struct || typ.Kind() == reflect.Map { return &tolerateEmptyArrayDecoder{decoder} } return decoder } type tolerateEmptyArrayDecoder struct { valDecoder jsoniter.ValDecoder } func (decoder *tolerateEmptyArrayDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { if iter.WhatIsNext() == jsoniter.ArrayValue { iter.Skip() newIter := iter.Pool().BorrowIterator([]byte("{}")) defer iter.Pool().ReturnIterator(newIter) decoder.valDecoder.Decode(ptr, newIter) } else { decoder.valDecoder.Decode(ptr, iter) } } type fuzzyStringDecoder struct { } func (decoder *fuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { valueType := iter.WhatIsNext() switch valueType { case jsoniter.NumberValue: var number json.Number iter.ReadVal(&number) *((*string)(ptr)) = string(number) case jsoniter.StringValue: *((*string)(ptr)) = iter.ReadString() case jsoniter.NilValue: iter.Skip() *((*string)(ptr)) = "" default: iter.ReportError("fuzzyStringDecoder", "not number or string") } } type fuzzyIntegerDecoder struct { fun func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) } func (decoder *fuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { valueType := iter.WhatIsNext() var str string switch valueType { case jsoniter.NumberValue: var number json.Number iter.ReadVal(&number) str = string(number) case jsoniter.StringValue: str = iter.ReadString() case jsoniter.BoolValue: if iter.ReadBool() { str = "1" } else { str = "0" } case jsoniter.NilValue: iter.Skip() str = "0" default: iter.ReportError("fuzzyIntegerDecoder", "not number or string") } if len(str) == 0 { str = "0" } newIter := iter.Pool().BorrowIterator([]byte(str)) defer iter.Pool().ReturnIterator(newIter) isFloat := strings.IndexByte(str, '.') != -1 decoder.fun(isFloat, ptr, newIter) if newIter.Error != nil && newIter.Error != io.EOF { iter.Error = newIter.Error } } type fuzzyFloat32Decoder struct { } func (decoder *fuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { valueType := iter.WhatIsNext() var str string switch valueType { case jsoniter.NumberValue: *((*float32)(ptr)) = iter.ReadFloat32() case jsoniter.StringValue: str = iter.ReadString() newIter := iter.Pool().BorrowIterator([]byte(str)) defer iter.Pool().ReturnIterator(newIter) *((*float32)(ptr)) = newIter.ReadFloat32() if newIter.Error != nil && newIter.Error != io.EOF { iter.Error = newIter.Error } case jsoniter.BoolValue: // support bool to float32 if iter.ReadBool() { *((*float32)(ptr)) = 1 } else { *((*float32)(ptr)) = 0 } case jsoniter.NilValue: iter.Skip() *((*float32)(ptr)) = 0 default: iter.ReportError("fuzzyFloat32Decoder", "not number or string") } } type fuzzyFloat64Decoder struct { } func (decoder *fuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { valueType := iter.WhatIsNext() var str string switch valueType { case jsoniter.NumberValue: *((*float64)(ptr)) = iter.ReadFloat64() case jsoniter.StringValue: str = iter.ReadString() newIter := iter.Pool().BorrowIterator([]byte(str)) defer iter.Pool().ReturnIterator(newIter) *((*float64)(ptr)) = newIter.ReadFloat64() if newIter.Error != nil && newIter.Error != io.EOF { iter.Error = newIter.Error } case jsoniter.BoolValue: // support bool to float64 if iter.ReadBool() { *((*float64)(ptr)) = 1 } else { *((*float64)(ptr)) = 0 } case jsoniter.NilValue: iter.Skip() *((*float64)(ptr)) = 0 default: iter.ReportError("fuzzyFloat64Decoder", "not number or string") } } golang-github-json-iterator-go-1.1.12/extra/fuzzy_decoder_test.go000066400000000000000000000302651420644465700251330ustar00rootroot00000000000000package extra import ( "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func init() { RegisterFuzzyDecoders() } func Test_any_to_string(t *testing.T) { should := require.New(t) var val string should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal("100", val) should.Nil(jsoniter.UnmarshalFromString("10", &val)) should.Equal("10", val) should.Nil(jsoniter.UnmarshalFromString("10.1", &val)) should.Equal("10.1", val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal("10.1", val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) } func Test_any_to_int64(t *testing.T) { should := require.New(t) var val int64 should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(int64(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(int64(10), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(int64(10), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(int64(10), val) should.Nil(jsoniter.UnmarshalFromString(`""`, &val)) should.Equal(int64(0), val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(int64(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(int64(1), val) should.Nil(jsoniter.UnmarshalFromString(`-10`, &val)) should.Equal(int64(-10), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) // large float to int should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val)) } func Test_any_to_int(t *testing.T) { should := require.New(t) var val int should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(100, val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(10, val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(10, val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(10, val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(0, val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(1, val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) // large float to int should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val)) } func Test_any_to_int16(t *testing.T) { should := require.New(t) var val int16 should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(int16(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(int16(10), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(int16(10), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(int16(10), val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(int16(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(int16(1), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) // large float to int should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val)) } func Test_any_to_int32(t *testing.T) { should := require.New(t) var val int32 should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(int32(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(int32(10), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(int32(10), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(int32(10), val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(int32(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(int32(1), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) // large float to int should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val)) } func Test_any_to_int8(t *testing.T) { should := require.New(t) var val int8 should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(int8(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(int8(10), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(int8(10), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(int8(10), val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(int8(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(int8(1), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) // large float to int should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val)) } func Test_any_to_uint8(t *testing.T) { should := require.New(t) var val uint8 should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(uint8(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(uint8(10), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(uint8(10), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(uint8(10), val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(uint8(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(uint8(1), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) // large float to int should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val)) } func Test_any_to_uint64(t *testing.T) { should := require.New(t) var val uint64 should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(uint64(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(uint64(10), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(uint64(10), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(uint64(10), val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(uint64(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(uint64(1), val) // TODO fix? should.NotNil(jsoniter.UnmarshalFromString(`-10`, &val)) should.Equal(uint64(0), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) // large float to int should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val)) } func Test_any_to_uint32(t *testing.T) { should := require.New(t) var val uint32 should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(uint32(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(uint32(10), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(uint32(10), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(uint32(10), val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(uint32(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(uint32(1), val) // TODO fix? should.NotNil(jsoniter.UnmarshalFromString(`-10`, &val)) should.Equal(uint32(0), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) // large float to int should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val)) } func Test_any_to_uint16(t *testing.T) { should := require.New(t) var val uint16 should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(uint16(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(uint16(10), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(uint16(10), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(uint16(10), val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(uint16(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(uint16(1), val) // TODO fix? should.NotNil(jsoniter.UnmarshalFromString(`-10`, &val)) should.Equal(uint16(0), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) // large float to int should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val)) } func Test_any_to_uint(t *testing.T) { should := require.New(t) var val uint should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(uint(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(uint(10), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(uint(10), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(uint(10), val) should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(uint(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(uint(1), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) // large float to int should.NotNil(jsoniter.UnmarshalFromString(`1234512345123451234512345.0`, &val)) } func Test_any_to_float32(t *testing.T) { should := require.New(t) var val float32 should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(float32(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(float32(10.1), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(float32(10.1), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(float32(10), val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(float32(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(float32(1), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) } func Test_any_to_float64(t *testing.T) { should := require.New(t) var val float64 should.Nil(jsoniter.UnmarshalFromString(`"100"`, &val)) should.Equal(float64(100), val) should.Nil(jsoniter.UnmarshalFromString(`"10.1"`, &val)) should.Equal(float64(10.1), val) should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val)) should.Equal(float64(10.1), val) should.Nil(jsoniter.UnmarshalFromString(`10`, &val)) should.Equal(float64(10), val) // bool part should.Nil(jsoniter.UnmarshalFromString(`false`, &val)) should.Equal(float64(0), val) should.Nil(jsoniter.UnmarshalFromString(`true`, &val)) should.Equal(float64(1), val) should.NotNil(jsoniter.UnmarshalFromString("{}", &val)) should.NotNil(jsoniter.UnmarshalFromString("[]", &val)) } func Test_empty_array_as_map(t *testing.T) { should := require.New(t) var val map[string]interface{} should.Nil(jsoniter.UnmarshalFromString(`[]`, &val)) should.Equal(map[string]interface{}{}, val) } func Test_empty_array_as_object(t *testing.T) { should := require.New(t) var val struct{} should.Nil(jsoniter.UnmarshalFromString(`[]`, &val)) should.Equal(struct{}{}, val) } func Test_bad_case(t *testing.T) { var jsonstr = ` { "extra_type": 181760, "combo_type": 0, "trigger_time_ms": 1498800398000, "_create_time": "2017-06-16 11:21:39", "_msg_type": 41000 } ` type OrderEventRequestParams struct { ExtraType uint64 `json:"extra_type"` } var a OrderEventRequestParams err := jsoniter.UnmarshalFromString(jsonstr, &a) should := require.New(t) should.Nil(err) } func Test_null_to_string(t *testing.T) { should := require.New(t) body := []byte(`null`) var message string err := jsoniter.Unmarshal(body, &message) should.NoError(err) } func Test_null_to_int(t *testing.T) { should := require.New(t) body := []byte(`null`) var message int err := jsoniter.Unmarshal(body, &message) should.NoError(err) } func Test_null_to_float32(t *testing.T) { should := require.New(t) body := []byte(`null`) var message float32 err := jsoniter.Unmarshal(body, &message) should.NoError(err) } func Test_null_to_float64(t *testing.T) { should := require.New(t) body := []byte(`null`) var message float64 err := jsoniter.Unmarshal(body, &message) should.NoError(err) } golang-github-json-iterator-go-1.1.12/extra/naming_strategy.go000066400000000000000000000027531420644465700244140ustar00rootroot00000000000000package extra import ( "github.com/json-iterator/go" "strings" "unicode" ) // SetNamingStrategy rename struct fields uniformly func SetNamingStrategy(translate func(string) string) { jsoniter.RegisterExtension(&namingStrategyExtension{jsoniter.DummyExtension{}, translate}) } type namingStrategyExtension struct { jsoniter.DummyExtension translate func(string) string } func (extension *namingStrategyExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) { for _, binding := range structDescriptor.Fields { if unicode.IsLower(rune(binding.Field.Name()[0])) || binding.Field.Name()[0] == '_'{ continue } tag, hastag := binding.Field.Tag().Lookup("json") if hastag { tagParts := strings.Split(tag, ",") if tagParts[0] == "-" { continue // hidden field } if tagParts[0] != "" { continue // field explicitly named } } binding.ToNames = []string{extension.translate(binding.Field.Name())} binding.FromNames = []string{extension.translate(binding.Field.Name())} } } // LowerCaseWithUnderscores one strategy to SetNamingStrategy for. It will change HelloWorld to hello_world. func LowerCaseWithUnderscores(name string) string { newName := []rune{} for i, c := range name { if i == 0 { newName = append(newName, unicode.ToLower(c)) } else { if unicode.IsUpper(c) { newName = append(newName, '_') newName = append(newName, unicode.ToLower(c)) } else { newName = append(newName, c) } } } return string(newName) } golang-github-json-iterator-go-1.1.12/extra/naming_strategy_test.go000066400000000000000000000033101420644465700254410ustar00rootroot00000000000000package extra import ( "github.com/json-iterator/go" "github.com/stretchr/testify/require" "testing" ) func Test_lower_case_with_underscores(t *testing.T) { should := require.New(t) should.Equal("hello_world", LowerCaseWithUnderscores("helloWorld")) should.Equal("hello_world", LowerCaseWithUnderscores("HelloWorld")) SetNamingStrategy(LowerCaseWithUnderscores) output, err := jsoniter.Marshal(struct { UserName string FirstLanguage string }{ UserName: "taowen", FirstLanguage: "Chinese", }) should.Nil(err) should.Equal(`{"user_name":"taowen","first_language":"Chinese"}`, string(output)) } func Test_set_naming_strategy_with_overrides(t *testing.T) { should := require.New(t) SetNamingStrategy(LowerCaseWithUnderscores) output, err := jsoniter.Marshal(struct { UserName string `json:"UserName"` FirstLanguage string }{ UserName: "taowen", FirstLanguage: "Chinese", }) should.Nil(err) should.Equal(`{"UserName":"taowen","first_language":"Chinese"}`, string(output)) } func Test_set_naming_strategy_with_omitempty(t *testing.T) { should := require.New(t) SetNamingStrategy(LowerCaseWithUnderscores) output, err := jsoniter.Marshal(struct { UserName string FirstLanguage string `json:",omitempty"` }{ UserName: "taowen", }) should.Nil(err) should.Equal(`{"user_name":"taowen"}`, string(output)) } func Test_set_naming_strategy_with_private_field(t *testing.T) { should := require.New(t) SetNamingStrategy(LowerCaseWithUnderscores) output, err := jsoniter.Marshal(struct { UserName string userId int _UserAge int }{ UserName: "allen", userId: 100, _UserAge: 30, }) should.Nil(err) should.Equal(`{"user_name":"allen"}`, string(output)) } golang-github-json-iterator-go-1.1.12/extra/privat_fields.go000066400000000000000000000025541420644465700240530ustar00rootroot00000000000000package extra import ( "github.com/json-iterator/go" "strings" "unicode" ) // SupportPrivateFields include private fields when encoding/decoding func SupportPrivateFields() { jsoniter.RegisterExtension(&privateFieldsExtension{}) } type privateFieldsExtension struct { jsoniter.DummyExtension } func (extension *privateFieldsExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) { for _, binding := range structDescriptor.Fields { isPrivate := unicode.IsLower(rune(binding.Field.Name()[0])) if isPrivate { tag, hastag := binding.Field.Tag().Lookup("json") if !hastag { binding.FromNames = []string{binding.Field.Name()} binding.ToNames = []string{binding.Field.Name()} continue } tagParts := strings.Split(tag, ",") names := calcFieldNames(binding.Field.Name(), tagParts[0], tag) binding.FromNames = names binding.ToNames = names } } } func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string { // ignore? if wholeTag == "-" { return []string{} } // rename? var fieldNames []string if tagProvidedFieldName == "" { fieldNames = []string{originalFieldName} } else { fieldNames = []string{tagProvidedFieldName} } // private? isNotExported := unicode.IsLower(rune(originalFieldName[0])) if isNotExported { fieldNames = []string{} } return fieldNames } golang-github-json-iterator-go-1.1.12/extra/private_fields_test.go000066400000000000000000000005641420644465700252560ustar00rootroot00000000000000package extra import ( "github.com/json-iterator/go" "github.com/stretchr/testify/require" "testing" ) func Test_private_fields(t *testing.T) { type TestObject struct { field1 string } SupportPrivateFields() should := require.New(t) obj := TestObject{} should.Nil(jsoniter.UnmarshalFromString(`{"field1":"Hello"}`, &obj)) should.Equal("Hello", obj.field1) } golang-github-json-iterator-go-1.1.12/extra/time_as_int64_codec.go000066400000000000000000000016741420644465700250240ustar00rootroot00000000000000package extra import ( "github.com/json-iterator/go" "time" "unsafe" ) // RegisterTimeAsInt64Codec encode/decode time since number of unit since epoch. the precision is the unit. func RegisterTimeAsInt64Codec(precision time.Duration) { jsoniter.RegisterTypeEncoder("time.Time", &timeAsInt64Codec{precision}) jsoniter.RegisterTypeDecoder("time.Time", &timeAsInt64Codec{precision}) } type timeAsInt64Codec struct { precision time.Duration } func (codec *timeAsInt64Codec) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { nanoseconds := iter.ReadInt64() * codec.precision.Nanoseconds() *((*time.Time)(ptr)) = time.Unix(0, nanoseconds) } func (codec *timeAsInt64Codec) IsEmpty(ptr unsafe.Pointer) bool { ts := *((*time.Time)(ptr)) return ts.UnixNano() == 0 } func (codec *timeAsInt64Codec) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) { ts := *((*time.Time)(ptr)) stream.WriteInt64(ts.UnixNano() / codec.precision.Nanoseconds()) } golang-github-json-iterator-go-1.1.12/extra/time_as_int64_codec_test.go000066400000000000000000000015311420644465700260530ustar00rootroot00000000000000package extra import ( "github.com/json-iterator/go" "github.com/stretchr/testify/require" "testing" "time" ) func Test_time_as_int64(t *testing.T) { should := require.New(t) RegisterTimeAsInt64Codec(time.Nanosecond) output, err := jsoniter.Marshal(time.Unix(1497952257, 1002)) should.Nil(err) should.Equal("1497952257000001002", string(output)) var val time.Time should.Nil(jsoniter.Unmarshal(output, &val)) should.Equal(int64(1497952257000001002), val.UnixNano()) } func Test_time_as_int64_keep_microsecond(t *testing.T) { t.Skip("conflict") should := require.New(t) RegisterTimeAsInt64Codec(time.Microsecond) output, err := jsoniter.Marshal(time.Unix(1, 1002)) should.Nil(err) should.Equal("1000001", string(output)) var val time.Time should.Nil(jsoniter.Unmarshal(output, &val)) should.Equal(int64(1000001000), val.UnixNano()) } golang-github-json-iterator-go-1.1.12/fuzzy_mode_convert_table.md000066400000000000000000000016371420644465700251730ustar00rootroot00000000000000| json type \ dest type | bool | int | uint | float |string| | --- | --- | --- | --- |--|--| | number | positive => true
negative => true
zero => false| 23.2 => 23
-32.1 => -32| 12.1 => 12
-12.1 => 0|as normal|same as origin| | string | empty string => false
string "0" => false
other strings => true | "123.32" => 123
"-123.4" => -123
"123.23xxxw" => 123
"abcde12" => 0
"-32.1" => -32| 13.2 => 13
-1.1 => 0 |12.1 => 12.1
-12.3 => -12.3
12.4xxa => 12.4
+1.1e2 =>110 |same as origin| | bool | true => true
false => false| true => 1
false => 0 | true => 1
false => 0 |true => 1
false => 0|true => "true"
false => "false"| | object | true | 0 | 0 |0|originnal json| | array | empty array => false
nonempty array => true| [] => 0
[1,2] => 1 | [] => 0
[1,2] => 1 |[] => 0
[1,2] => 1|original json|golang-github-json-iterator-go-1.1.12/go.mod000066400000000000000000000004131420644465700206440ustar00rootroot00000000000000module github.com/json-iterator/go go 1.12 require ( github.com/davecgh/go-spew v1.1.1 github.com/google/gofuzz v1.0.0 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 github.com/modern-go/reflect2 v1.0.2 github.com/stretchr/testify v1.3.0 ) golang-github-json-iterator-go-1.1.12/go.sum000066400000000000000000000023761420644465700207030ustar00rootroot00000000000000github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= golang-github-json-iterator-go-1.1.12/iter.go000066400000000000000000000173311420644465700210370ustar00rootroot00000000000000package jsoniter import ( "encoding/json" "fmt" "io" ) // ValueType the type for JSON element type ValueType int const ( // InvalidValue invalid JSON element InvalidValue ValueType = iota // StringValue JSON element "string" StringValue // NumberValue JSON element 100 or 0.10 NumberValue // NilValue JSON element null NilValue // BoolValue JSON element true or false BoolValue // ArrayValue JSON element [] ArrayValue // ObjectValue JSON element {} ObjectValue ) var hexDigits []byte var valueTypes []ValueType func init() { hexDigits = make([]byte, 256) for i := 0; i < len(hexDigits); i++ { hexDigits[i] = 255 } for i := '0'; i <= '9'; i++ { hexDigits[i] = byte(i - '0') } for i := 'a'; i <= 'f'; i++ { hexDigits[i] = byte((i - 'a') + 10) } for i := 'A'; i <= 'F'; i++ { hexDigits[i] = byte((i - 'A') + 10) } valueTypes = make([]ValueType, 256) for i := 0; i < len(valueTypes); i++ { valueTypes[i] = InvalidValue } valueTypes['"'] = StringValue valueTypes['-'] = NumberValue valueTypes['0'] = NumberValue valueTypes['1'] = NumberValue valueTypes['2'] = NumberValue valueTypes['3'] = NumberValue valueTypes['4'] = NumberValue valueTypes['5'] = NumberValue valueTypes['6'] = NumberValue valueTypes['7'] = NumberValue valueTypes['8'] = NumberValue valueTypes['9'] = NumberValue valueTypes['t'] = BoolValue valueTypes['f'] = BoolValue valueTypes['n'] = NilValue valueTypes['['] = ArrayValue valueTypes['{'] = ObjectValue } // Iterator is a io.Reader like object, with JSON specific read functions. // Error is not returned as return value, but stored as Error member on this iterator instance. type Iterator struct { cfg *frozenConfig reader io.Reader buf []byte head int tail int depth int captureStartedAt int captured []byte Error error Attachment interface{} // open for customized decoder } // NewIterator creates an empty Iterator instance func NewIterator(cfg API) *Iterator { return &Iterator{ cfg: cfg.(*frozenConfig), reader: nil, buf: nil, head: 0, tail: 0, depth: 0, } } // Parse creates an Iterator instance from io.Reader func Parse(cfg API, reader io.Reader, bufSize int) *Iterator { return &Iterator{ cfg: cfg.(*frozenConfig), reader: reader, buf: make([]byte, bufSize), head: 0, tail: 0, depth: 0, } } // ParseBytes creates an Iterator instance from byte array func ParseBytes(cfg API, input []byte) *Iterator { return &Iterator{ cfg: cfg.(*frozenConfig), reader: nil, buf: input, head: 0, tail: len(input), depth: 0, } } // ParseString creates an Iterator instance from string func ParseString(cfg API, input string) *Iterator { return ParseBytes(cfg, []byte(input)) } // Pool returns a pool can provide more iterator with same configuration func (iter *Iterator) Pool() IteratorPool { return iter.cfg } // Reset reuse iterator instance by specifying another reader func (iter *Iterator) Reset(reader io.Reader) *Iterator { iter.reader = reader iter.head = 0 iter.tail = 0 iter.depth = 0 return iter } // ResetBytes reuse iterator instance by specifying another byte array as input func (iter *Iterator) ResetBytes(input []byte) *Iterator { iter.reader = nil iter.buf = input iter.head = 0 iter.tail = len(input) iter.depth = 0 return iter } // WhatIsNext gets ValueType of relatively next json element func (iter *Iterator) WhatIsNext() ValueType { valueType := valueTypes[iter.nextToken()] iter.unreadByte() return valueType } func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool { for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] switch c { case ' ', '\n', '\t', '\r': continue } iter.head = i return false } return true } func (iter *Iterator) isObjectEnd() bool { c := iter.nextToken() if c == ',' { return false } if c == '}' { return true } iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c})) return true } func (iter *Iterator) nextToken() byte { // a variation of skip whitespaces, returning the next non-whitespace token for { for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] switch c { case ' ', '\n', '\t', '\r': continue } iter.head = i + 1 return c } if !iter.loadMore() { return 0 } } } // ReportError record a error in iterator instance with current position. func (iter *Iterator) ReportError(operation string, msg string) { if iter.Error != nil { if iter.Error != io.EOF { return } } peekStart := iter.head - 10 if peekStart < 0 { peekStart = 0 } peekEnd := iter.head + 10 if peekEnd > iter.tail { peekEnd = iter.tail } parsing := string(iter.buf[peekStart:peekEnd]) contextStart := iter.head - 50 if contextStart < 0 { contextStart = 0 } contextEnd := iter.head + 50 if contextEnd > iter.tail { contextEnd = iter.tail } context := string(iter.buf[contextStart:contextEnd]) iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...", operation, msg, iter.head-peekStart, parsing, context) } // CurrentBuffer gets current buffer as string for debugging purpose func (iter *Iterator) CurrentBuffer() string { peekStart := iter.head - 10 if peekStart < 0 { peekStart = 0 } return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head, string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) } func (iter *Iterator) readByte() (ret byte) { if iter.head == iter.tail { if iter.loadMore() { ret = iter.buf[iter.head] iter.head++ return ret } return 0 } ret = iter.buf[iter.head] iter.head++ return ret } func (iter *Iterator) loadMore() bool { if iter.reader == nil { if iter.Error == nil { iter.head = iter.tail iter.Error = io.EOF } return false } if iter.captured != nil { iter.captured = append(iter.captured, iter.buf[iter.captureStartedAt:iter.tail]...) iter.captureStartedAt = 0 } for { n, err := iter.reader.Read(iter.buf) if n == 0 { if err != nil { if iter.Error == nil { iter.Error = err } return false } } else { iter.head = 0 iter.tail = n return true } } } func (iter *Iterator) unreadByte() { if iter.Error != nil { return } iter.head-- return } // Read read the next JSON element as generic interface{}. func (iter *Iterator) Read() interface{} { valueType := iter.WhatIsNext() switch valueType { case StringValue: return iter.ReadString() case NumberValue: if iter.cfg.configBeforeFrozen.UseNumber { return json.Number(iter.readNumberAsString()) } return iter.ReadFloat64() case NilValue: iter.skipFourBytes('n', 'u', 'l', 'l') return nil case BoolValue: return iter.ReadBool() case ArrayValue: arr := []interface{}{} iter.ReadArrayCB(func(iter *Iterator) bool { var elem interface{} iter.ReadVal(&elem) arr = append(arr, elem) return true }) return arr case ObjectValue: obj := map[string]interface{}{} iter.ReadMapCB(func(Iter *Iterator, field string) bool { var elem interface{} iter.ReadVal(&elem) obj[field] = elem return true }) return obj default: iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType)) return nil } } // limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9 const maxDepth = 10000 func (iter *Iterator) incrementDepth() (success bool) { iter.depth++ if iter.depth <= maxDepth { return true } iter.ReportError("incrementDepth", "exceeded max depth") return false } func (iter *Iterator) decrementDepth() (success bool) { iter.depth-- if iter.depth >= 0 { return true } iter.ReportError("decrementDepth", "unexpected negative nesting") return false } golang-github-json-iterator-go-1.1.12/iter_array.go000066400000000000000000000025721420644465700222360ustar00rootroot00000000000000package jsoniter // ReadArray read array element, tells if the array has more element to read. func (iter *Iterator) ReadArray() (ret bool) { c := iter.nextToken() switch c { case 'n': iter.skipThreeBytes('u', 'l', 'l') return false // null case '[': c = iter.nextToken() if c != ']' { iter.unreadByte() return true } return false case ']': return false case ',': return true default: iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c})) return } } // ReadArrayCB read array with callback func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { c := iter.nextToken() if c == '[' { if !iter.incrementDepth() { return false } c = iter.nextToken() if c != ']' { iter.unreadByte() if !callback(iter) { iter.decrementDepth() return false } c = iter.nextToken() for c == ',' { if !callback(iter) { iter.decrementDepth() return false } c = iter.nextToken() } if c != ']' { iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) iter.decrementDepth() return false } return iter.decrementDepth() } return iter.decrementDepth() } if c == 'n' { iter.skipThreeBytes('u', 'l', 'l') return true // null } iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c})) return false } golang-github-json-iterator-go-1.1.12/iter_float.go000066400000000000000000000167311420644465700222270ustar00rootroot00000000000000package jsoniter import ( "encoding/json" "io" "math/big" "strconv" "strings" "unsafe" ) var floatDigits []int8 const invalidCharForNumber = int8(-1) const endOfNumber = int8(-2) const dotInNumber = int8(-3) func init() { floatDigits = make([]int8, 256) for i := 0; i < len(floatDigits); i++ { floatDigits[i] = invalidCharForNumber } for i := int8('0'); i <= int8('9'); i++ { floatDigits[i] = i - int8('0') } floatDigits[','] = endOfNumber floatDigits[']'] = endOfNumber floatDigits['}'] = endOfNumber floatDigits[' '] = endOfNumber floatDigits['\t'] = endOfNumber floatDigits['\n'] = endOfNumber floatDigits['.'] = dotInNumber } // ReadBigFloat read big.Float func (iter *Iterator) ReadBigFloat() (ret *big.Float) { str := iter.readNumberAsString() if iter.Error != nil && iter.Error != io.EOF { return nil } prec := 64 if len(str) > prec { prec = len(str) } val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero) if err != nil { iter.Error = err return nil } return val } // ReadBigInt read big.Int func (iter *Iterator) ReadBigInt() (ret *big.Int) { str := iter.readNumberAsString() if iter.Error != nil && iter.Error != io.EOF { return nil } ret = big.NewInt(0) var success bool ret, success = ret.SetString(str, 10) if !success { iter.ReportError("ReadBigInt", "invalid big int") return nil } return ret } //ReadFloat32 read float32 func (iter *Iterator) ReadFloat32() (ret float32) { c := iter.nextToken() if c == '-' { return -iter.readPositiveFloat32() } iter.unreadByte() return iter.readPositiveFloat32() } func (iter *Iterator) readPositiveFloat32() (ret float32) { i := iter.head // first char if i == iter.tail { return iter.readFloat32SlowPath() } c := iter.buf[i] i++ ind := floatDigits[c] switch ind { case invalidCharForNumber: return iter.readFloat32SlowPath() case endOfNumber: iter.ReportError("readFloat32", "empty number") return case dotInNumber: iter.ReportError("readFloat32", "leading dot is invalid") return case 0: if i == iter.tail { return iter.readFloat32SlowPath() } c = iter.buf[i] switch c { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': iter.ReportError("readFloat32", "leading zero is invalid") return } } value := uint64(ind) // chars before dot non_decimal_loop: for ; i < iter.tail; i++ { c = iter.buf[i] ind := floatDigits[c] switch ind { case invalidCharForNumber: return iter.readFloat32SlowPath() case endOfNumber: iter.head = i return float32(value) case dotInNumber: break non_decimal_loop } if value > uint64SafeToMultiple10 { return iter.readFloat32SlowPath() } value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; } // chars after dot if c == '.' { i++ decimalPlaces := 0 if i == iter.tail { return iter.readFloat32SlowPath() } for ; i < iter.tail; i++ { c = iter.buf[i] ind := floatDigits[c] switch ind { case endOfNumber: if decimalPlaces > 0 && decimalPlaces < len(pow10) { iter.head = i return float32(float64(value) / float64(pow10[decimalPlaces])) } // too many decimal places return iter.readFloat32SlowPath() case invalidCharForNumber, dotInNumber: return iter.readFloat32SlowPath() } decimalPlaces++ if value > uint64SafeToMultiple10 { return iter.readFloat32SlowPath() } value = (value << 3) + (value << 1) + uint64(ind) } } return iter.readFloat32SlowPath() } func (iter *Iterator) readNumberAsString() (ret string) { strBuf := [16]byte{} str := strBuf[0:0] load_loop: for { for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] switch c { case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': str = append(str, c) continue default: iter.head = i break load_loop } } if !iter.loadMore() { break } } if iter.Error != nil && iter.Error != io.EOF { return } if len(str) == 0 { iter.ReportError("readNumberAsString", "invalid number") } return *(*string)(unsafe.Pointer(&str)) } func (iter *Iterator) readFloat32SlowPath() (ret float32) { str := iter.readNumberAsString() if iter.Error != nil && iter.Error != io.EOF { return } errMsg := validateFloat(str) if errMsg != "" { iter.ReportError("readFloat32SlowPath", errMsg) return } val, err := strconv.ParseFloat(str, 32) if err != nil { iter.Error = err return } return float32(val) } // ReadFloat64 read float64 func (iter *Iterator) ReadFloat64() (ret float64) { c := iter.nextToken() if c == '-' { return -iter.readPositiveFloat64() } iter.unreadByte() return iter.readPositiveFloat64() } func (iter *Iterator) readPositiveFloat64() (ret float64) { i := iter.head // first char if i == iter.tail { return iter.readFloat64SlowPath() } c := iter.buf[i] i++ ind := floatDigits[c] switch ind { case invalidCharForNumber: return iter.readFloat64SlowPath() case endOfNumber: iter.ReportError("readFloat64", "empty number") return case dotInNumber: iter.ReportError("readFloat64", "leading dot is invalid") return case 0: if i == iter.tail { return iter.readFloat64SlowPath() } c = iter.buf[i] switch c { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': iter.ReportError("readFloat64", "leading zero is invalid") return } } value := uint64(ind) // chars before dot non_decimal_loop: for ; i < iter.tail; i++ { c = iter.buf[i] ind := floatDigits[c] switch ind { case invalidCharForNumber: return iter.readFloat64SlowPath() case endOfNumber: iter.head = i return float64(value) case dotInNumber: break non_decimal_loop } if value > uint64SafeToMultiple10 { return iter.readFloat64SlowPath() } value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; } // chars after dot if c == '.' { i++ decimalPlaces := 0 if i == iter.tail { return iter.readFloat64SlowPath() } for ; i < iter.tail; i++ { c = iter.buf[i] ind := floatDigits[c] switch ind { case endOfNumber: if decimalPlaces > 0 && decimalPlaces < len(pow10) { iter.head = i return float64(value) / float64(pow10[decimalPlaces]) } // too many decimal places return iter.readFloat64SlowPath() case invalidCharForNumber, dotInNumber: return iter.readFloat64SlowPath() } decimalPlaces++ if value > uint64SafeToMultiple10 { return iter.readFloat64SlowPath() } value = (value << 3) + (value << 1) + uint64(ind) if value > maxFloat64 { return iter.readFloat64SlowPath() } } } return iter.readFloat64SlowPath() } func (iter *Iterator) readFloat64SlowPath() (ret float64) { str := iter.readNumberAsString() if iter.Error != nil && iter.Error != io.EOF { return } errMsg := validateFloat(str) if errMsg != "" { iter.ReportError("readFloat64SlowPath", errMsg) return } val, err := strconv.ParseFloat(str, 64) if err != nil { iter.Error = err return } return val } func validateFloat(str string) string { // strconv.ParseFloat is not validating `1.` or `1.e1` if len(str) == 0 { return "empty number" } if str[0] == '-' { return "-- is not valid" } dotPos := strings.IndexByte(str, '.') if dotPos != -1 { if dotPos == len(str)-1 { return "dot can not be last character" } switch str[dotPos+1] { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': default: return "missing digit after dot" } } return "" } // ReadNumber read json.Number func (iter *Iterator) ReadNumber() (ret json.Number) { return json.Number(iter.readNumberAsString()) } golang-github-json-iterator-go-1.1.12/iter_int.go000066400000000000000000000211011420644465700216770ustar00rootroot00000000000000package jsoniter import ( "math" "strconv" ) var intDigits []int8 const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1 const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1 const maxFloat64 = 1<<53 - 1 func init() { intDigits = make([]int8, 256) for i := 0; i < len(intDigits); i++ { intDigits[i] = invalidCharForNumber } for i := int8('0'); i <= int8('9'); i++ { intDigits[i] = i - int8('0') } } // ReadUint read uint func (iter *Iterator) ReadUint() uint { if strconv.IntSize == 32 { return uint(iter.ReadUint32()) } return uint(iter.ReadUint64()) } // ReadInt read int func (iter *Iterator) ReadInt() int { if strconv.IntSize == 32 { return int(iter.ReadInt32()) } return int(iter.ReadInt64()) } // ReadInt8 read int8 func (iter *Iterator) ReadInt8() (ret int8) { c := iter.nextToken() if c == '-' { val := iter.readUint32(iter.readByte()) if val > math.MaxInt8+1 { iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) return } return -int8(val) } val := iter.readUint32(c) if val > math.MaxInt8 { iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) return } return int8(val) } // ReadUint8 read uint8 func (iter *Iterator) ReadUint8() (ret uint8) { val := iter.readUint32(iter.nextToken()) if val > math.MaxUint8 { iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10)) return } return uint8(val) } // ReadInt16 read int16 func (iter *Iterator) ReadInt16() (ret int16) { c := iter.nextToken() if c == '-' { val := iter.readUint32(iter.readByte()) if val > math.MaxInt16+1 { iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) return } return -int16(val) } val := iter.readUint32(c) if val > math.MaxInt16 { iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) return } return int16(val) } // ReadUint16 read uint16 func (iter *Iterator) ReadUint16() (ret uint16) { val := iter.readUint32(iter.nextToken()) if val > math.MaxUint16 { iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10)) return } return uint16(val) } // ReadInt32 read int32 func (iter *Iterator) ReadInt32() (ret int32) { c := iter.nextToken() if c == '-' { val := iter.readUint32(iter.readByte()) if val > math.MaxInt32+1 { iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) return } return -int32(val) } val := iter.readUint32(c) if val > math.MaxInt32 { iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) return } return int32(val) } // ReadUint32 read uint32 func (iter *Iterator) ReadUint32() (ret uint32) { return iter.readUint32(iter.nextToken()) } func (iter *Iterator) readUint32(c byte) (ret uint32) { ind := intDigits[c] if ind == 0 { iter.assertInteger() return 0 // single zero } if ind == invalidCharForNumber { iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)})) return } value := uint32(ind) if iter.tail-iter.head > 10 { i := iter.head ind2 := intDigits[iter.buf[i]] if ind2 == invalidCharForNumber { iter.head = i iter.assertInteger() return value } i++ ind3 := intDigits[iter.buf[i]] if ind3 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*10 + uint32(ind2) } //iter.head = i + 1 //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) i++ ind4 := intDigits[iter.buf[i]] if ind4 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*100 + uint32(ind2)*10 + uint32(ind3) } i++ ind5 := intDigits[iter.buf[i]] if ind5 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4) } i++ ind6 := intDigits[iter.buf[i]] if ind6 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5) } i++ ind7 := intDigits[iter.buf[i]] if ind7 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6) } i++ ind8 := intDigits[iter.buf[i]] if ind8 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7) } i++ ind9 := intDigits[iter.buf[i]] value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8) iter.head = i if ind9 == invalidCharForNumber { iter.assertInteger() return value } } for { for i := iter.head; i < iter.tail; i++ { ind = intDigits[iter.buf[i]] if ind == invalidCharForNumber { iter.head = i iter.assertInteger() return value } if value > uint32SafeToMultiply10 { value2 := (value << 3) + (value << 1) + uint32(ind) if value2 < value { iter.ReportError("readUint32", "overflow") return } value = value2 continue } value = (value << 3) + (value << 1) + uint32(ind) } if !iter.loadMore() { iter.assertInteger() return value } } } // ReadInt64 read int64 func (iter *Iterator) ReadInt64() (ret int64) { c := iter.nextToken() if c == '-' { val := iter.readUint64(iter.readByte()) if val > math.MaxInt64+1 { iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) return } return -int64(val) } val := iter.readUint64(c) if val > math.MaxInt64 { iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) return } return int64(val) } // ReadUint64 read uint64 func (iter *Iterator) ReadUint64() uint64 { return iter.readUint64(iter.nextToken()) } func (iter *Iterator) readUint64(c byte) (ret uint64) { ind := intDigits[c] if ind == 0 { iter.assertInteger() return 0 // single zero } if ind == invalidCharForNumber { iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)})) return } value := uint64(ind) if iter.tail-iter.head > 10 { i := iter.head ind2 := intDigits[iter.buf[i]] if ind2 == invalidCharForNumber { iter.head = i iter.assertInteger() return value } i++ ind3 := intDigits[iter.buf[i]] if ind3 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*10 + uint64(ind2) } //iter.head = i + 1 //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) i++ ind4 := intDigits[iter.buf[i]] if ind4 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*100 + uint64(ind2)*10 + uint64(ind3) } i++ ind5 := intDigits[iter.buf[i]] if ind5 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4) } i++ ind6 := intDigits[iter.buf[i]] if ind6 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5) } i++ ind7 := intDigits[iter.buf[i]] if ind7 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6) } i++ ind8 := intDigits[iter.buf[i]] if ind8 == invalidCharForNumber { iter.head = i iter.assertInteger() return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7) } i++ ind9 := intDigits[iter.buf[i]] value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8) iter.head = i if ind9 == invalidCharForNumber { iter.assertInteger() return value } } for { for i := iter.head; i < iter.tail; i++ { ind = intDigits[iter.buf[i]] if ind == invalidCharForNumber { iter.head = i iter.assertInteger() return value } if value > uint64SafeToMultiple10 { value2 := (value << 3) + (value << 1) + uint64(ind) if value2 < value { iter.ReportError("readUint64", "overflow") return } value = value2 continue } value = (value << 3) + (value << 1) + uint64(ind) } if !iter.loadMore() { iter.assertInteger() return value } } } func (iter *Iterator) assertInteger() { if iter.head < iter.tail && iter.buf[iter.head] == '.' { iter.ReportError("assertInteger", "can not decode float as int") } } golang-github-json-iterator-go-1.1.12/iter_object.go000066400000000000000000000143321420644465700223630ustar00rootroot00000000000000package jsoniter import ( "fmt" "strings" ) // ReadObject read one field from object. // If object ended, returns empty string. // Otherwise, returns the field name. func (iter *Iterator) ReadObject() (ret string) { c := iter.nextToken() switch c { case 'n': iter.skipThreeBytes('u', 'l', 'l') return "" // null case '{': c = iter.nextToken() if c == '"' { iter.unreadByte() field := iter.ReadString() c = iter.nextToken() if c != ':' { iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) } return field } if c == '}' { return "" // end of object } iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) return case ',': field := iter.ReadString() c = iter.nextToken() if c != ':' { iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) } return field case '}': return "" // end of object default: iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c}))) return } } // CaseInsensitive func (iter *Iterator) readFieldHash() int64 { hash := int64(0x811c9dc5) c := iter.nextToken() if c != '"' { iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) return 0 } for { for i := iter.head; i < iter.tail; i++ { // require ascii string and no escape b := iter.buf[i] if b == '\\' { iter.head = i for _, b := range iter.readStringSlowPath() { if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { b += 'a' - 'A' } hash ^= int64(b) hash *= 0x1000193 } c = iter.nextToken() if c != ':' { iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) return 0 } return hash } if b == '"' { iter.head = i + 1 c = iter.nextToken() if c != ':' { iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) return 0 } return hash } if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { b += 'a' - 'A' } hash ^= int64(b) hash *= 0x1000193 } if !iter.loadMore() { iter.ReportError("readFieldHash", `incomplete field name`) return 0 } } } func calcHash(str string, caseSensitive bool) int64 { if !caseSensitive { str = strings.ToLower(str) } hash := int64(0x811c9dc5) for _, b := range []byte(str) { hash ^= int64(b) hash *= 0x1000193 } return int64(hash) } // ReadObjectCB read object with callback, the key is ascii only and field name not copied func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { c := iter.nextToken() var field string if c == '{' { if !iter.incrementDepth() { return false } c = iter.nextToken() if c == '"' { iter.unreadByte() field = iter.ReadString() c = iter.nextToken() if c != ':' { iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) } if !callback(iter, field) { iter.decrementDepth() return false } c = iter.nextToken() for c == ',' { field = iter.ReadString() c = iter.nextToken() if c != ':' { iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) } if !callback(iter, field) { iter.decrementDepth() return false } c = iter.nextToken() } if c != '}' { iter.ReportError("ReadObjectCB", `object not ended with }`) iter.decrementDepth() return false } return iter.decrementDepth() } if c == '}' { return iter.decrementDepth() } iter.ReportError("ReadObjectCB", `expect " after {, but found `+string([]byte{c})) iter.decrementDepth() return false } if c == 'n' { iter.skipThreeBytes('u', 'l', 'l') return true // null } iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) return false } // ReadMapCB read map with callback, the key can be any string func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { c := iter.nextToken() if c == '{' { if !iter.incrementDepth() { return false } c = iter.nextToken() if c == '"' { iter.unreadByte() field := iter.ReadString() if iter.nextToken() != ':' { iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) iter.decrementDepth() return false } if !callback(iter, field) { iter.decrementDepth() return false } c = iter.nextToken() for c == ',' { field = iter.ReadString() if iter.nextToken() != ':' { iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) iter.decrementDepth() return false } if !callback(iter, field) { iter.decrementDepth() return false } c = iter.nextToken() } if c != '}' { iter.ReportError("ReadMapCB", `object not ended with }`) iter.decrementDepth() return false } return iter.decrementDepth() } if c == '}' { return iter.decrementDepth() } iter.ReportError("ReadMapCB", `expect " after {, but found `+string([]byte{c})) iter.decrementDepth() return false } if c == 'n' { iter.skipThreeBytes('u', 'l', 'l') return true // null } iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) return false } func (iter *Iterator) readObjectStart() bool { c := iter.nextToken() if c == '{' { c = iter.nextToken() if c == '}' { return false } iter.unreadByte() return true } else if c == 'n' { iter.skipThreeBytes('u', 'l', 'l') return false } iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) return false } func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { str := iter.ReadStringAsSlice() if iter.skipWhitespacesWithoutLoadMore() { if ret == nil { ret = make([]byte, len(str)) copy(ret, str) } if !iter.loadMore() { return } } if iter.buf[iter.head] != ':' { iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) return } iter.head++ if iter.skipWhitespacesWithoutLoadMore() { if ret == nil { ret = make([]byte, len(str)) copy(ret, str) } if !iter.loadMore() { return } } if ret == nil { return str } return ret } golang-github-json-iterator-go-1.1.12/iter_skip.go000066400000000000000000000065451420644465700220720ustar00rootroot00000000000000package jsoniter import "fmt" // ReadNil reads a json object as nil and // returns whether it's a nil or not func (iter *Iterator) ReadNil() (ret bool) { c := iter.nextToken() if c == 'n' { iter.skipThreeBytes('u', 'l', 'l') // null return true } iter.unreadByte() return false } // ReadBool reads a json object as BoolValue func (iter *Iterator) ReadBool() (ret bool) { c := iter.nextToken() if c == 't' { iter.skipThreeBytes('r', 'u', 'e') return true } if c == 'f' { iter.skipFourBytes('a', 'l', 's', 'e') return false } iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c})) return } // SkipAndReturnBytes skip next JSON element, and return its content as []byte. // The []byte can be kept, it is a copy of data. func (iter *Iterator) SkipAndReturnBytes() []byte { iter.startCapture(iter.head) iter.Skip() return iter.stopCapture() } // SkipAndAppendBytes skips next JSON element and appends its content to // buffer, returning the result. func (iter *Iterator) SkipAndAppendBytes(buf []byte) []byte { iter.startCaptureTo(buf, iter.head) iter.Skip() return iter.stopCapture() } func (iter *Iterator) startCaptureTo(buf []byte, captureStartedAt int) { if iter.captured != nil { panic("already in capture mode") } iter.captureStartedAt = captureStartedAt iter.captured = buf } func (iter *Iterator) startCapture(captureStartedAt int) { iter.startCaptureTo(make([]byte, 0, 32), captureStartedAt) } func (iter *Iterator) stopCapture() []byte { if iter.captured == nil { panic("not in capture mode") } captured := iter.captured remaining := iter.buf[iter.captureStartedAt:iter.head] iter.captureStartedAt = -1 iter.captured = nil return append(captured, remaining...) } // Skip skips a json object and positions to relatively the next json object func (iter *Iterator) Skip() { c := iter.nextToken() switch c { case '"': iter.skipString() case 'n': iter.skipThreeBytes('u', 'l', 'l') // null case 't': iter.skipThreeBytes('r', 'u', 'e') // true case 'f': iter.skipFourBytes('a', 'l', 's', 'e') // false case '0': iter.unreadByte() iter.ReadFloat32() case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': iter.skipNumber() case '[': iter.skipArray() case '{': iter.skipObject() default: iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c)) return } } func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) { if iter.readByte() != b1 { iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) return } if iter.readByte() != b2 { iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) return } if iter.readByte() != b3 { iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) return } if iter.readByte() != b4 { iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) return } } func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) { if iter.readByte() != b1 { iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) return } if iter.readByte() != b2 { iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) return } if iter.readByte() != b3 { iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) return } } golang-github-json-iterator-go-1.1.12/iter_skip_sloppy.go000066400000000000000000000062671420644465700235010ustar00rootroot00000000000000//+build jsoniter_sloppy package jsoniter // sloppy but faster implementation, do not validate the input json func (iter *Iterator) skipNumber() { for { for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] switch c { case ' ', '\n', '\r', '\t', ',', '}', ']': iter.head = i return } } if !iter.loadMore() { return } } } func (iter *Iterator) skipArray() { level := 1 if !iter.incrementDepth() { return } for { for i := iter.head; i < iter.tail; i++ { switch iter.buf[i] { case '"': // If inside string, skip it iter.head = i + 1 iter.skipString() i = iter.head - 1 // it will be i++ soon case '[': // If open symbol, increase level level++ if !iter.incrementDepth() { return } case ']': // If close symbol, increase level level-- if !iter.decrementDepth() { return } // If we have returned to the original level, we're done if level == 0 { iter.head = i + 1 return } } } if !iter.loadMore() { iter.ReportError("skipObject", "incomplete array") return } } } func (iter *Iterator) skipObject() { level := 1 if !iter.incrementDepth() { return } for { for i := iter.head; i < iter.tail; i++ { switch iter.buf[i] { case '"': // If inside string, skip it iter.head = i + 1 iter.skipString() i = iter.head - 1 // it will be i++ soon case '{': // If open symbol, increase level level++ if !iter.incrementDepth() { return } case '}': // If close symbol, increase level level-- if !iter.decrementDepth() { return } // If we have returned to the original level, we're done if level == 0 { iter.head = i + 1 return } } } if !iter.loadMore() { iter.ReportError("skipObject", "incomplete object") return } } } func (iter *Iterator) skipString() { for { end, escaped := iter.findStringEnd() if end == -1 { if !iter.loadMore() { iter.ReportError("skipString", "incomplete string") return } if escaped { iter.head = 1 // skip the first char as last char read is \ } } else { iter.head = end return } } } // adapted from: https://github.com/buger/jsonparser/blob/master/parser.go // Tries to find the end of string // Support if string contains escaped quote symbols. func (iter *Iterator) findStringEnd() (int, bool) { escaped := false for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] if c == '"' { if !escaped { return i + 1, false } j := i - 1 for { if j < iter.head || iter.buf[j] != '\\' { // even number of backslashes // either end of buffer, or " found return i + 1, true } j-- if j < iter.head || iter.buf[j] != '\\' { // odd number of backslashes // it is \" or \\\" break } j-- } } else if c == '\\' { escaped = true } } j := iter.tail - 1 for { if j < iter.head || iter.buf[j] != '\\' { // even number of backslashes // either end of buffer, or " found return -1, false // do not end with \ } j-- if j < iter.head || iter.buf[j] != '\\' { // odd number of backslashes // it is \" or \\\" break } j-- } return -1, true // end with \ } golang-github-json-iterator-go-1.1.12/iter_skip_sloppy_test.go000066400000000000000000000061361420644465700245330ustar00rootroot00000000000000//+build jsoniter_sloppy package jsoniter import ( "github.com/stretchr/testify/require" "io" "testing" ) func Test_string_end(t *testing.T) { end, escaped := ParseString(ConfigDefault, `abc"`).findStringEnd() if end != 4 { t.Fatal(end) } if escaped != false { t.Fatal(escaped) } end, escaped = ParseString(ConfigDefault, `abc\\"`).findStringEnd() if end != 6 { t.Fatal(end) } if escaped != true { t.Fatal(escaped) } end, escaped = ParseString(ConfigDefault, `abc\\\\"`).findStringEnd() if end != 8 { t.Fatal(end) } if escaped != true { t.Fatal(escaped) } end, escaped = ParseString(ConfigDefault, `abc\"`).findStringEnd() if end != -1 { t.Fatal(end) } if escaped != false { t.Fatal(escaped) } end, escaped = ParseString(ConfigDefault, `abc\`).findStringEnd() if end != -1 { t.Fatal(end) } if escaped != true { t.Fatal(escaped) } end, escaped = ParseString(ConfigDefault, `abc\\`).findStringEnd() if end != -1 { t.Fatal(end) } if escaped != false { t.Fatal(escaped) } end, escaped = ParseString(ConfigDefault, `\\`).findStringEnd() if end != -1 { t.Fatal(end) } if escaped != false { t.Fatal(escaped) } end, escaped = ParseString(ConfigDefault, `\`).findStringEnd() if end != -1 { t.Fatal(end) } if escaped != true { t.Fatal(escaped) } } type StagedReader struct { r1 string r2 string r3 string r int } func (reader *StagedReader) Read(p []byte) (n int, err error) { reader.r++ switch reader.r { case 1: copy(p, []byte(reader.r1)) return len(reader.r1), nil case 2: copy(p, []byte(reader.r2)) return len(reader.r2), nil case 3: copy(p, []byte(reader.r3)) return len(reader.r3), nil default: return 0, io.EOF } } func Test_skip_string(t *testing.T) { should := require.New(t) iter := ParseString(ConfigDefault, `"abc`) iter.skipString() should.Equal(1, iter.head) iter = ParseString(ConfigDefault, `\""abc`) iter.skipString() should.Equal(3, iter.head) reader := &StagedReader{ r1: `abc`, r2: `"`, } iter = Parse(ConfigDefault, reader, 4096) iter.skipString() should.Equal(1, iter.head) reader = &StagedReader{ r1: `abc`, r2: `1"`, } iter = Parse(ConfigDefault, reader, 4096) iter.skipString() should.Equal(2, iter.head) reader = &StagedReader{ r1: `abc\`, r2: `"`, } iter = Parse(ConfigDefault, reader, 4096) iter.skipString() should.NotNil(iter.Error) reader = &StagedReader{ r1: `abc\`, r2: `""`, } iter = Parse(ConfigDefault, reader, 4096) iter.skipString() should.Equal(2, iter.head) } func Test_skip_object(t *testing.T) { iter := ParseString(ConfigDefault, `}`) iter.skipObject() if iter.head != 1 { t.Fatal(iter.head) } iter = ParseString(ConfigDefault, `a}`) iter.skipObject() if iter.head != 2 { t.Fatal(iter.head) } iter = ParseString(ConfigDefault, `{}}a`) iter.skipObject() if iter.head != 3 { t.Fatal(iter.head) } reader := &StagedReader{ r1: `{`, r2: `}}a`, } iter = Parse(ConfigDefault, reader, 4096) iter.skipObject() if iter.head != 2 { t.Fatal(iter.head) } iter = ParseString(ConfigDefault, `"}"}a`) iter.skipObject() if iter.head != 4 { t.Fatal(iter.head) } } golang-github-json-iterator-go-1.1.12/iter_skip_strict.go000066400000000000000000000037221420644465700234540ustar00rootroot00000000000000//+build !jsoniter_sloppy package jsoniter import ( "fmt" "io" ) func (iter *Iterator) skipNumber() { if !iter.trySkipNumber() { iter.unreadByte() if iter.Error != nil && iter.Error != io.EOF { return } iter.ReadFloat64() if iter.Error != nil && iter.Error != io.EOF { iter.Error = nil iter.ReadBigFloat() } } } func (iter *Iterator) trySkipNumber() bool { dotFound := false for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] switch c { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': case '.': if dotFound { iter.ReportError("validateNumber", `more than one dot found in number`) return true // already failed } if i+1 == iter.tail { return false } c = iter.buf[i+1] switch c { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': default: iter.ReportError("validateNumber", `missing digit after dot`) return true // already failed } dotFound = true default: switch c { case ',', ']', '}', ' ', '\t', '\n', '\r': if iter.head == i { return false // if - without following digits } iter.head = i return true // must be valid } return false // may be invalid } } return false } func (iter *Iterator) skipString() { if !iter.trySkipString() { iter.unreadByte() iter.ReadString() } } func (iter *Iterator) trySkipString() bool { for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] if c == '"' { iter.head = i + 1 return true // valid } else if c == '\\' { return false } else if c < ' ' { iter.ReportError("trySkipString", fmt.Sprintf(`invalid control character found: %d`, c)) return true // already failed } } return false } func (iter *Iterator) skipObject() { iter.unreadByte() iter.ReadObjectCB(func(iter *Iterator, field string) bool { iter.Skip() return true }) } func (iter *Iterator) skipArray() { iter.unreadByte() iter.ReadArrayCB(func(iter *Iterator) bool { iter.Skip() return true }) } golang-github-json-iterator-go-1.1.12/iter_str.go000066400000000000000000000113251420644465700217240ustar00rootroot00000000000000package jsoniter import ( "fmt" "unicode/utf16" ) // ReadString read string from iterator func (iter *Iterator) ReadString() (ret string) { c := iter.nextToken() if c == '"' { for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] if c == '"' { ret = string(iter.buf[iter.head:i]) iter.head = i + 1 return ret } else if c == '\\' { break } else if c < ' ' { iter.ReportError("ReadString", fmt.Sprintf(`invalid control character found: %d`, c)) return } } return iter.readStringSlowPath() } else if c == 'n' { iter.skipThreeBytes('u', 'l', 'l') return "" } iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c})) return } func (iter *Iterator) readStringSlowPath() (ret string) { var str []byte var c byte for iter.Error == nil { c = iter.readByte() if c == '"' { return string(str) } if c == '\\' { c = iter.readByte() str = iter.readEscapedChar(c, str) } else { str = append(str, c) } } iter.ReportError("readStringSlowPath", "unexpected end of input") return } func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte { switch c { case 'u': r := iter.readU4() if utf16.IsSurrogate(r) { c = iter.readByte() if iter.Error != nil { return nil } if c != '\\' { iter.unreadByte() str = appendRune(str, r) return str } c = iter.readByte() if iter.Error != nil { return nil } if c != 'u' { str = appendRune(str, r) return iter.readEscapedChar(c, str) } r2 := iter.readU4() if iter.Error != nil { return nil } combined := utf16.DecodeRune(r, r2) if combined == '\uFFFD' { str = appendRune(str, r) str = appendRune(str, r2) } else { str = appendRune(str, combined) } } else { str = appendRune(str, r) } case '"': str = append(str, '"') case '\\': str = append(str, '\\') case '/': str = append(str, '/') case 'b': str = append(str, '\b') case 'f': str = append(str, '\f') case 'n': str = append(str, '\n') case 'r': str = append(str, '\r') case 't': str = append(str, '\t') default: iter.ReportError("readEscapedChar", `invalid escape char after \`) return nil } return str } // ReadStringAsSlice read string from iterator without copying into string form. // The []byte can not be kept, as it will change after next iterator call. func (iter *Iterator) ReadStringAsSlice() (ret []byte) { c := iter.nextToken() if c == '"' { for i := iter.head; i < iter.tail; i++ { // require ascii string and no escape // for: field name, base64, number if iter.buf[i] == '"' { // fast path: reuse the underlying buffer ret = iter.buf[iter.head:i] iter.head = i + 1 return ret } } readLen := iter.tail - iter.head copied := make([]byte, readLen, readLen*2) copy(copied, iter.buf[iter.head:iter.tail]) iter.head = iter.tail for iter.Error == nil { c := iter.readByte() if c == '"' { return copied } copied = append(copied, c) } return copied } iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c})) return } func (iter *Iterator) readU4() (ret rune) { for i := 0; i < 4; i++ { c := iter.readByte() if iter.Error != nil { return } if c >= '0' && c <= '9' { ret = ret*16 + rune(c-'0') } else if c >= 'a' && c <= 'f' { ret = ret*16 + rune(c-'a'+10) } else if c >= 'A' && c <= 'F' { ret = ret*16 + rune(c-'A'+10) } else { iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c})) return } } return ret } const ( t1 = 0x00 // 0000 0000 tx = 0x80 // 1000 0000 t2 = 0xC0 // 1100 0000 t3 = 0xE0 // 1110 0000 t4 = 0xF0 // 1111 0000 t5 = 0xF8 // 1111 1000 maskx = 0x3F // 0011 1111 mask2 = 0x1F // 0001 1111 mask3 = 0x0F // 0000 1111 mask4 = 0x07 // 0000 0111 rune1Max = 1<<7 - 1 rune2Max = 1<<11 - 1 rune3Max = 1<<16 - 1 surrogateMin = 0xD800 surrogateMax = 0xDFFF maxRune = '\U0010FFFF' // Maximum valid Unicode code point. runeError = '\uFFFD' // the "error" Rune or "Unicode replacement character" ) func appendRune(p []byte, r rune) []byte { // Negative values are erroneous. Making it unsigned addresses the problem. switch i := uint32(r); { case i <= rune1Max: p = append(p, byte(r)) return p case i <= rune2Max: p = append(p, t2|byte(r>>6)) p = append(p, tx|byte(r)&maskx) return p case i > maxRune, surrogateMin <= i && i <= surrogateMax: r = runeError fallthrough case i <= rune3Max: p = append(p, t3|byte(r>>12)) p = append(p, tx|byte(r>>6)&maskx) p = append(p, tx|byte(r)&maskx) return p default: p = append(p, t4|byte(r>>18)) p = append(p, tx|byte(r>>12)&maskx) p = append(p, tx|byte(r>>6)&maskx) p = append(p, tx|byte(r)&maskx) return p } } golang-github-json-iterator-go-1.1.12/jsoniter.go000066400000000000000000000015641420644465700217320ustar00rootroot00000000000000// Package jsoniter implements encoding and decoding of JSON as defined in // RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json. // Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter // and variable type declarations (if any). // jsoniter interfaces gives 100% compatibility with code using standard lib. // // "JSON and Go" // (https://golang.org/doc/articles/json_and_go.html) // gives a description of how Marshal/Unmarshal operate // between arbitrary or predefined json objects and bytes, // and it applies to jsoniter.Marshal/Unmarshal as well. // // Besides, jsoniter.Iterator provides a different set of interfaces // iterating given bytes/string/reader // and yielding parsed elements one by one. // This set of interfaces reads input as required and gives // better performance. package jsoniter golang-github-json-iterator-go-1.1.12/misc_tests/000077500000000000000000000000001420644465700217155ustar00rootroot00000000000000golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_array_test.go000066400000000000000000000140121420644465700263340ustar00rootroot00000000000000package misc_tests import ( "bytes" "encoding/json" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_empty_array(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[]`) cont := iter.ReadArray() should.False(cont) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `[]`) iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool { should.FailNow("should not call") return true }) } func Test_one_element(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1]`) should.True(iter.ReadArray()) should.Equal(1, iter.ReadInt()) should.False(iter.ReadArray()) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `[1]`) iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool { should.Equal(1, iter.ReadInt()) return true }) } func Test_two_elements(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1,2]`) should.True(iter.ReadArray()) should.Equal(int64(1), iter.ReadInt64()) should.True(iter.ReadArray()) should.Equal(int64(2), iter.ReadInt64()) should.False(iter.ReadArray()) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `[1,2]`) should.Equal([]interface{}{float64(1), float64(2)}, iter.Read()) } func Test_whitespace_in_head(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, ` [1]`) cont := iter.ReadArray() if cont != true { t.FailNow() } if iter.ReadUint64() != 1 { t.FailNow() } } func Test_whitespace_after_array_start(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[ 1]`) cont := iter.ReadArray() if cont != true { t.FailNow() } if iter.ReadUint64() != 1 { t.FailNow() } } func Test_whitespace_before_array_end(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1 ]`) cont := iter.ReadArray() if cont != true { t.FailNow() } if iter.ReadUint64() != 1 { t.FailNow() } cont = iter.ReadArray() if cont != false { t.FailNow() } } func Test_whitespace_before_comma(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1 ,2]`) cont := iter.ReadArray() if cont != true { t.FailNow() } if iter.ReadUint64() != 1 { t.FailNow() } cont = iter.ReadArray() if cont != true { t.FailNow() } if iter.ReadUint64() != 2 { t.FailNow() } cont = iter.ReadArray() if cont != false { t.FailNow() } } func Test_write_array(t *testing.T) { should := require.New(t) buf := &bytes.Buffer{} stream := jsoniter.NewStream(jsoniter.Config{IndentionStep: 2}.Froze(), buf, 4096) stream.WriteArrayStart() stream.WriteInt(1) stream.WriteMore() stream.WriteInt(2) stream.WriteArrayEnd() stream.Flush() should.Nil(stream.Error) should.Equal("[\n 1,\n 2\n]", buf.String()) } func Test_write_val_array(t *testing.T) { should := require.New(t) val := []int{1, 2, 3} str, err := jsoniter.MarshalToString(&val) should.Nil(err) should.Equal("[1,2,3]", str) } func Test_write_val_empty_array(t *testing.T) { should := require.New(t) val := []int{} str, err := jsoniter.MarshalToString(val) should.Nil(err) should.Equal("[]", str) } func Test_write_array_of_interface_in_struct(t *testing.T) { should := require.New(t) type TestObject struct { Field []interface{} Field2 string } val := TestObject{[]interface{}{1, 2}, ""} str, err := jsoniter.MarshalToString(val) should.Nil(err) should.Contains(str, `"Field":[1,2]`) should.Contains(str, `"Field2":""`) } func Test_encode_byte_array(t *testing.T) { should := require.New(t) bytes, err := json.Marshal([]byte{1, 2, 3}) should.Nil(err) should.Equal(`"AQID"`, string(bytes)) bytes, err = jsoniter.Marshal([]byte{1, 2, 3}) should.Nil(err) should.Equal(`"AQID"`, string(bytes)) } func Test_encode_empty_byte_array(t *testing.T) { should := require.New(t) bytes, err := json.Marshal([]byte{}) should.Nil(err) should.Equal(`""`, string(bytes)) bytes, err = jsoniter.Marshal([]byte{}) should.Nil(err) should.Equal(`""`, string(bytes)) } func Test_encode_nil_byte_array(t *testing.T) { should := require.New(t) var nilSlice []byte bytes, err := json.Marshal(nilSlice) should.Nil(err) should.Equal(`null`, string(bytes)) bytes, err = jsoniter.Marshal(nilSlice) should.Nil(err) should.Equal(`null`, string(bytes)) } func Test_decode_byte_array_from_base64(t *testing.T) { should := require.New(t) data := []byte{} err := json.Unmarshal([]byte(`"AQID"`), &data) should.Nil(err) should.Equal([]byte{1, 2, 3}, data) err = jsoniter.Unmarshal([]byte(`"AQID"`), &data) should.Nil(err) should.Equal([]byte{1, 2, 3}, data) } func Test_decode_byte_array_from_base64_with_newlines(t *testing.T) { should := require.New(t) data := []byte{} err := json.Unmarshal([]byte(`"A\rQ\nID"`), &data) should.Nil(err) should.Equal([]byte{1, 2, 3}, data) err = jsoniter.Unmarshal([]byte(`"A\rQ\nID"`), &data) should.Nil(err) should.Equal([]byte{1, 2, 3}, data) } func Test_decode_byte_array_from_array(t *testing.T) { should := require.New(t) data := []byte{} err := json.Unmarshal([]byte(`[1,2,3]`), &data) should.Nil(err) should.Equal([]byte{1, 2, 3}, data) err = jsoniter.Unmarshal([]byte(`[1,2,3]`), &data) should.Nil(err) should.Equal([]byte{1, 2, 3}, data) } func Test_decode_slice(t *testing.T) { should := require.New(t) slice := make([]string, 0, 5) jsoniter.UnmarshalFromString(`["hello", "world"]`, &slice) should.Equal([]string{"hello", "world"}, slice) } func Test_decode_large_slice(t *testing.T) { should := require.New(t) slice := make([]int, 0, 1) jsoniter.UnmarshalFromString(`[1,2,3,4,5,6,7,8,9]`, &slice) should.Equal([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, slice) } func Benchmark_jsoniter_array(b *testing.B) { b.ReportAllocs() input := []byte(`[1,2,3,4,5,6,7,8,9]`) iter := jsoniter.ParseBytes(jsoniter.ConfigDefault, input) b.ResetTimer() for n := 0; n < b.N; n++ { iter.ResetBytes(input) for iter.ReadArray() { iter.ReadUint64() } } } func Benchmark_json_array(b *testing.B) { for n := 0; n < b.N; n++ { result := []interface{}{} json.Unmarshal([]byte(`[1,2,3]`), &result) } } golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_bool_test.go000066400000000000000000000022221420644465700261510ustar00rootroot00000000000000package misc_tests import ( "bytes" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_true(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `true`) should.True(iter.ReadBool()) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `true`) should.Equal(true, iter.Read()) } func Test_false(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `false`) should.False(iter.ReadBool()) } func Test_write_true_false(t *testing.T) { should := require.New(t) buf := &bytes.Buffer{} stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096) stream.WriteTrue() stream.WriteFalse() stream.WriteBool(false) stream.Flush() should.Nil(stream.Error) should.Equal("truefalsefalse", buf.String()) } func Test_write_val_bool(t *testing.T) { should := require.New(t) buf := &bytes.Buffer{} stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096) stream.WriteVal(true) should.Equal(stream.Buffered(), 4) stream.Flush() should.Equal(stream.Buffered(), 0) should.Nil(stream.Error) should.Equal("true", buf.String()) } golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_float_test.go000066400000000000000000000062071420644465700263320ustar00rootroot00000000000000package misc_tests import ( "encoding/json" "math" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_read_big_float(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `12.3`) val := iter.ReadBigFloat() val64, _ := val.Float64() should.Equal(12.3, val64) } func Test_read_big_int(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `92233720368547758079223372036854775807`) val := iter.ReadBigInt() should.NotNil(val) should.Equal(`92233720368547758079223372036854775807`, val.String()) } func Test_read_float_as_interface(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `12.3`) should.Equal(float64(12.3), iter.Read()) } func Test_wrap_float(t *testing.T) { should := require.New(t) str, err := jsoniter.MarshalToString(jsoniter.WrapFloat64(12.3)) should.Nil(err) should.Equal("12.3", str) } func Test_read_float64_cursor(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, "[1.23456789\n,2,3]") should.True(iter.ReadArray()) should.Equal(1.23456789, iter.Read()) should.True(iter.ReadArray()) should.Equal(float64(2), iter.Read()) } func Test_read_float_scientific(t *testing.T) { should := require.New(t) var obj interface{} should.NoError(jsoniter.UnmarshalFromString(`1e1`, &obj)) should.Equal(float64(10), obj) should.NoError(json.Unmarshal([]byte(`1e1`), &obj)) should.Equal(float64(10), obj) should.NoError(jsoniter.UnmarshalFromString(`1.0e1`, &obj)) should.Equal(float64(10), obj) should.NoError(json.Unmarshal([]byte(`1.0e1`), &obj)) should.Equal(float64(10), obj) } func Test_lossy_float_marshal(t *testing.T) { should := require.New(t) api := jsoniter.Config{MarshalFloatWith6Digits: true}.Froze() output, err := api.MarshalToString(float64(0.1234567)) should.Nil(err) should.Equal("0.123457", output) output, err = api.MarshalToString(float32(0.1234567)) should.Nil(err) should.Equal("0.123457", output) } func Test_read_number(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `92233720368547758079223372036854775807`) val := iter.ReadNumber() should.Equal(`92233720368547758079223372036854775807`, string(val)) } func Test_encode_inf(t *testing.T) { should := require.New(t) _, err := json.Marshal(math.Inf(1)) should.Error(err) _, err = jsoniter.Marshal(float32(math.Inf(1))) should.Error(err) _, err = jsoniter.Marshal(math.Inf(-1)) should.Error(err) } func Test_encode_nan(t *testing.T) { should := require.New(t) _, err := json.Marshal(math.NaN()) should.Error(err) _, err = jsoniter.Marshal(float32(math.NaN())) should.Error(err) _, err = jsoniter.Marshal(math.NaN()) should.Error(err) } func Benchmark_jsoniter_float(b *testing.B) { b.ReportAllocs() input := []byte(`1.1123,`) iter := jsoniter.NewIterator(jsoniter.ConfigDefault) for n := 0; n < b.N; n++ { iter.ResetBytes(input) iter.ReadFloat64() } } func Benchmark_json_float(b *testing.B) { for n := 0; n < b.N; n++ { result := float64(0) json.Unmarshal([]byte(`1.1`), &result) } } golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_int_test.go000066400000000000000000000107401420644465700260140ustar00rootroot00000000000000// +build go1.8 package misc_tests import ( "bytes" "encoding/json" "io" "io/ioutil" "math/rand" "strconv" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_read_uint64_invalid(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, ",") iter.ReadUint64() should.NotNil(iter.Error) } func Test_read_int32_array(t *testing.T) { should := require.New(t) input := `[123,456,789]` val := make([]int32, 0) jsoniter.UnmarshalFromString(input, &val) should.Equal(3, len(val)) } func Test_read_int64_array(t *testing.T) { should := require.New(t) input := `[123,456,789]` val := make([]int64, 0) jsoniter.UnmarshalFromString(input, &val) should.Equal(3, len(val)) } func Test_wrap_int(t *testing.T) { should := require.New(t) str, err := jsoniter.MarshalToString(jsoniter.WrapInt64(100)) should.Nil(err) should.Equal("100", str) } func Test_write_val_int(t *testing.T) { should := require.New(t) buf := &bytes.Buffer{} stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096) stream.WriteVal(1001) stream.Flush() should.Nil(stream.Error) should.Equal("1001", buf.String()) } func Test_write_val_int_ptr(t *testing.T) { should := require.New(t) buf := &bytes.Buffer{} stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096) val := 1001 stream.WriteVal(&val) stream.Flush() should.Nil(stream.Error) should.Equal("1001", buf.String()) } func Test_float_as_int(t *testing.T) { should := require.New(t) var i int should.NotNil(jsoniter.Unmarshal([]byte(`1.1`), &i)) } // chunkedData is io.Reader which returns random amount of data in range [1, chunkedData.chunkSize]. // It simulates chunked data on from HTTP server, which is commonly used by net/http package. type chunkedData struct { chunkSize int data []byte head int } // Read is implementation of the io.Reader which returns random amount of data in range [1, chunkedData.chunkSize]. func (c *chunkedData) Read(p []byte) (n int, err error) { to := c.head + int(rand.Int31n(int32(c.chunkSize))+1) // copy does not copy more data then p can consume n = copy(p, c.data[c.head:to]) c.head = c.head + n if c.head >= len(c.data) { err = io.EOF } return n, err } // TestIterator_ReadInt_chunkedInput validates the behaviour of Iterator.ReadInt() method in where: // - it reads data from io.Reader, // - expected value is 0 (zero) // - Iterator.tail == Iterator.head // - Iterator.tail < len(Iterator.buf) // - value in buffer after Iterator.tail is presented from previous read and has '.' character. func TestIterator_ReadInt_chunkedInput(t *testing.T) { should := require.New(t) data := &chunkedData{ data: jsonFloatIntArray(t, 10), } // because this test is rely on randomness of chunkedData, we are doing multiple iterations to // be sure, that we can hit a required case. for data.chunkSize = 3; data.chunkSize <= len(data.data); data.chunkSize++ { data.head = 0 iter := jsoniter.Parse(jsoniter.ConfigDefault, data, data.chunkSize) i := 0 for iter.ReadArray() { // every even item is float, let's just skip it. if i%2 == 0 { iter.Skip() i++ continue } should.Zero(iter.ReadInt()) should.NoError(iter.Error) i++ } } } // jsonFloatIntArray generates JSON array where every // - even item is float 0.1 // - odd item is integer 0 // // [0.1, 0, 0.1, 0] func jsonFloatIntArray(t *testing.T, numberOfItems int) []byte { t.Helper() numbers := make([]jsoniter.Any, numberOfItems) for i := range numbers { switch i % 2 { case 0: numbers[i] = jsoniter.WrapFloat64(0.1) default: numbers[i] = jsoniter.WrapInt64(0) } } fixture, err := jsoniter.ConfigFastest.Marshal(numbers) if err != nil { panic(err) } b := &bytes.Buffer{} require.NoError( t, json.Compact(b, fixture), "json should be compactable", ) return b.Bytes() } func Benchmark_jsoniter_encode_int(b *testing.B) { stream := jsoniter.NewStream(jsoniter.ConfigDefault, ioutil.Discard, 64) for n := 0; n < b.N; n++ { stream.Reset(nil) stream.WriteUint64(0xffffffff) } } func Benchmark_itoa(b *testing.B) { for n := 0; n < b.N; n++ { strconv.FormatInt(0xffffffff, 10) } } func Benchmark_jsoniter_int(b *testing.B) { iter := jsoniter.NewIterator(jsoniter.ConfigDefault) input := []byte(`100`) for n := 0; n < b.N; n++ { iter.ResetBytes(input) iter.ReadInt64() } } func Benchmark_json_int(b *testing.B) { for n := 0; n < b.N; n++ { result := int64(0) json.Unmarshal([]byte(`-100`), &result) } } golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_interface_test.go000066400000000000000000000077661420644465700272000ustar00rootroot00000000000000package misc_tests import ( "encoding/json" "github.com/json-iterator/go" "github.com/stretchr/testify/require" "io" "testing" ) func Test_nil_non_empty_interface(t *testing.T) { type TestObject struct { Field []io.Closer } should := require.New(t) obj := TestObject{} b := []byte(`{"Field":["AAA"]}`) should.NotNil(json.Unmarshal(b, &obj)) should.NotNil(jsoniter.Unmarshal(b, &obj)) } func Test_nil_out_null_interface(t *testing.T) { type TestData struct { Field interface{} `json:"field"` } should := require.New(t) var boolVar bool obj := TestData{ Field: &boolVar, } data1 := []byte(`{"field": true}`) err := jsoniter.Unmarshal(data1, &obj) should.NoError(err) should.Equal(true, *(obj.Field.(*bool))) data2 := []byte(`{"field": null}`) err = jsoniter.Unmarshal(data2, &obj) should.NoError(err) should.Nil(obj.Field) // Checking stdlib behavior matches. obj2 := TestData{ Field: &boolVar, } err = json.Unmarshal(data1, &obj2) should.NoError(err) should.Equal(true, *(obj2.Field.(*bool))) err = json.Unmarshal(data2, &obj2) should.NoError(err) should.Equal(nil, obj2.Field) } func Test_overwrite_interface_ptr_value_with_nil(t *testing.T) { type Wrapper struct { Payload interface{} `json:"payload,omitempty"` } type Payload struct { Value int `json:"val,omitempty"` } should := require.New(t) payload := &Payload{} wrapper := &Wrapper{ Payload: &payload, } err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper) should.NoError(err) should.Equal(&payload, wrapper.Payload) should.Equal(42, (*(wrapper.Payload.(**Payload))).Value) err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper) should.NoError(err) should.Equal(&payload, wrapper.Payload) should.Equal((*Payload)(nil), payload) payload = &Payload{} wrapper = &Wrapper{ Payload: &payload, } err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper) should.Equal(nil, err) should.Equal(&payload, wrapper.Payload) should.Equal(42, (*(wrapper.Payload.(**Payload))).Value) err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper) should.NoError(err) should.Equal(&payload, wrapper.Payload) should.Equal((*Payload)(nil), payload) } func Test_overwrite_interface_value_with_nil(t *testing.T) { type Wrapper struct { Payload interface{} `json:"payload,omitempty"` } type Payload struct { Value int `json:"val,omitempty"` } should := require.New(t) payload := &Payload{} wrapper := &Wrapper{ Payload: payload, } err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper) should.NoError(err) should.Equal(42, wrapper.Payload.(*Payload).Value) err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper) should.NoError(err) should.Equal(nil, wrapper.Payload) should.Equal(42, payload.Value) payload = &Payload{} wrapper = &Wrapper{ Payload: payload, } err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper) should.Equal(nil, err) should.Equal(42, wrapper.Payload.(*Payload).Value) err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper) should.Equal(nil, err) should.Equal(nil, wrapper.Payload) should.Equal(42, payload.Value) } func Test_unmarshal_into_nil(t *testing.T) { type Payload struct { Value int `json:"val,omitempty"` } type Wrapper struct { Payload interface{} `json:"payload,omitempty"` } should := require.New(t) var payload *Payload wrapper := &Wrapper{ Payload: payload, } err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper) should.NoError(err) should.NotNil(wrapper.Payload) should.Nil(payload) err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper) should.NoError(err) should.Nil(wrapper.Payload) should.Nil(payload) payload = nil wrapper = &Wrapper{ Payload: payload, } err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper) should.NoError(err) should.NotNil(wrapper.Payload) should.Nil(payload) err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper) should.NoError(err) should.Nil(wrapper.Payload) should.Nil(payload) } golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_iterator_test.go000066400000000000000000000734641420644465700270670ustar00rootroot00000000000000package misc_tests import ( "bytes" "encoding/json" "fmt" "strconv" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_bad_case(t *testing.T) { // field := *(*string)(unsafe.Pointer(&str)) // caused this issue iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(`{"Info":{"InfoHash":"4lzhP/fwlVLRgalC31YbfBSiqwo=","InfoHashstr":"E25CE13FF7F09552D181A942DF561B7C14A2AB0A","AnnounceList":["http://tracker.nwps.ws:6969/announce","http://tracker.nwps.ws:6969/announce","http://tracker.winglai.com/announce","http://fr33dom.h33t.com:3310/announce","http://exodus.desync.com:6969/announce","http://torrent.gresille.org/announce","http://tracker.trackerfix.com/announce","udp://tracker.btzoo.eu:80/announce","http://tracker.windsormetalbattery.com/announce","udp://10.rarbg.me:80/announce","udp://ipv4.tracker.harry.lu:80/announce","udp://tracker.ilibr.org:6969/announce","udp://tracker.zond.org:80/announce","http://torrent-tracker.ru/announce.php","http://bigfoot1942.sektori.org:6969/announce","http://tracker.best-torrents.net:6969/announce","http://announce.torrentsmd.com:6969/announce","udp://tracker.token.ro:80/announce","udp://tracker.coppersurfer.tk:80","http://tracker.thepiratebay.org/announce","udp://9.rarbg.com:2710/announce","udp://open.demonii.com:1337/announce","udp://tracker.ccc.de:80/announce","udp://tracker.istole.it:80/announce","udp://tracker.publicbt.com:80/announce","udp://tracker.openbittorrent.com:80/announce","udp://tracker.istole.it:80/announce","http://tracker.istole.it/announce","udp://tracker.publicbt.com:80/announce","http://tracker.publicbt.com/announce","udp://open.demonii.com:1337/announce"],"Length":2434793890,"PieceSize":524288,"PieceNum":4645},"InfoHashstr":"E25CE13FF7F09552D181A942DF561B7C14A2AB0A","SectionNum":32,"PieceNum":4645,"PieceSize":16384,"Finished":false,"SparseSize":104857600,"Bit":[{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":4645,"EndIndex":580,"EndMask":248,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}]}`), 4096) count := 0 for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { if field == "Bit" { for iter.ReadArray() { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { if field == "Bit" { iter.ReadStringAsSlice() } else { if field != "Size" && field != "EndIndex" && field != "EndMask" && field != "Good" && field != "Flush" { t.Fatal(field) } iter.Skip() } } count++ } } else { iter.Skip() } } if count != 32 { t.Fatal(count) } } func Test_iterator_use_number(t *testing.T) { // Test UseNumber with iterator Read() inputs := []string{`2147483647`, `-2147483648`} for _, input := range inputs { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.Config{UseNumber: true}.Froze(), input) expected := json.Number(input) should.Equal(expected, iter.Read()) }) } } func Test_iterator_without_number(t *testing.T) { inputs := []string{`2147483647`, `-2147483648`} for _, input := range inputs { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, input) expected, err := strconv.ParseInt(input, 10, 32) should.Nil(err) should.Equal(float64(expected), iter.Read()) }) } } golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_map_test.go000066400000000000000000000046041420644465700260010ustar00rootroot00000000000000package misc_tests import ( "encoding/json" "math/big" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" "strings" ) func Test_decode_TextMarshaler_key_map(t *testing.T) { should := require.New(t) var val map[*big.Float]string should.Nil(jsoniter.UnmarshalFromString(`{"1":"2"}`, &val)) str, err := jsoniter.MarshalToString(val) should.Nil(err) should.Equal(`{"1":"2"}`, str) } func Test_read_map_with_reader(t *testing.T) { should := require.New(t) input := `{"branch":"beta","change_log":"add the rows{10}","channel":"fros","create_time":"2017-06-13 16:39:08","firmware_list":"","md5":"80dee2bf7305bcf179582088e29fd7b9","note":{"CoreServices":{"md5":"d26975c0a8c7369f70ed699f2855cc2e","package_name":"CoreServices","version_code":"76","version_name":"1.0.76"},"FrDaemon":{"md5":"6b1f0626673200bc2157422cd2103f5d","package_name":"FrDaemon","version_code":"390","version_name":"1.0.390"},"FrGallery":{"md5":"90d767f0f31bcd3c1d27281ec979ba65","package_name":"FrGallery","version_code":"349","version_name":"1.0.349"},"FrLocal":{"md5":"f15a215b2c070a80a01f07bde4f219eb","package_name":"FrLocal","version_code":"791","version_name":"1.0.791"}},"pack_region_urls":{"CN":"https://s3.cn-north-1.amazonaws.com.cn/xxx-os/ttt_xxx_android_1.5.3.344.393.zip","default":"http://192.168.8.78/ttt_xxx_android_1.5.3.344.393.zip","local":"http://192.168.8.78/ttt_xxx_android_1.5.3.344.393.zip"},"pack_version":"1.5.3.344.393","pack_version_code":393,"region":"all","release_flag":0,"revision":62,"size":38966875,"status":3}` reader := strings.NewReader(input) decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(reader) m1 := map[string]interface{}{} should.Nil(decoder.Decode(&m1)) m2 := map[string]interface{}{} should.Nil(json.Unmarshal([]byte(input), &m2)) should.Equal(m2, m1) should.Equal("1.0.76", m1["note"].(map[string]interface{})["CoreServices"].(map[string]interface{})["version_name"]) } func Test_map_eface_of_eface(t *testing.T) { should := require.New(t) json := jsoniter.ConfigCompatibleWithStandardLibrary output, err := json.MarshalToString(map[interface{}]interface{}{ "1": 2, 3: "4", }) should.NoError(err) should.Equal(`{"1":2,"3":"4"}`, output) } func Test_encode_nil_map(t *testing.T) { should := require.New(t) var nilMap map[string]string output, err := jsoniter.MarshalToString(nilMap) should.NoError(err) should.Equal(`null`, output) } golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_nested_test.go000066400000000000000000000157211420644465700265100ustar00rootroot00000000000000package misc_tests import ( "encoding/json" "github.com/json-iterator/go" "reflect" "strings" "testing" ) type Level1 struct { Hello []Level2 } type Level2 struct { World string } func Test_deep_nested(t *testing.T) { type unstructured interface{} testcases := []struct { name string data []byte expectError string }{ { name: "array under maxDepth", data: []byte(`{"a":` + strings.Repeat(`[`, 10000-1) + strings.Repeat(`]`, 10000-1) + `}`), expectError: "", }, { name: "array over maxDepth", data: []byte(`{"a":` + strings.Repeat(`[`, 10000) + strings.Repeat(`]`, 10000) + `}`), expectError: "max depth", }, { name: "object under maxDepth", data: []byte(`{"a":` + strings.Repeat(`{"a":`, 10000-1) + `0` + strings.Repeat(`}`, 10000-1) + `}`), expectError: "", }, { name: "object over maxDepth", data: []byte(`{"a":` + strings.Repeat(`{"a":`, 10000) + `0` + strings.Repeat(`}`, 10000) + `}`), expectError: "max depth", }, } targets := []struct { name string new func() interface{} }{ { name: "unstructured", new: func() interface{} { var v interface{} return &v }, }, { name: "typed named field", new: func() interface{} { v := struct { A interface{} `json:"a"` }{} return &v }, }, { name: "typed missing field", new: func() interface{} { v := struct { B interface{} `json:"b"` }{} return &v }, }, { name: "typed 1 field", new: func() interface{} { v := struct { A interface{} `json:"a"` }{} return &v }, }, { name: "typed 2 field", new: func() interface{} { v := struct { A interface{} `json:"a"` B interface{} `json:"b"` }{} return &v }, }, { name: "typed 3 field", new: func() interface{} { v := struct { A interface{} `json:"a"` B interface{} `json:"b"` C interface{} `json:"c"` }{} return &v }, }, { name: "typed 4 field", new: func() interface{} { v := struct { A interface{} `json:"a"` B interface{} `json:"b"` C interface{} `json:"c"` D interface{} `json:"d"` }{} return &v }, }, { name: "typed 5 field", new: func() interface{} { v := struct { A interface{} `json:"a"` B interface{} `json:"b"` C interface{} `json:"c"` D interface{} `json:"d"` E interface{} `json:"e"` }{} return &v }, }, { name: "typed 6 field", new: func() interface{} { v := struct { A interface{} `json:"a"` B interface{} `json:"b"` C interface{} `json:"c"` D interface{} `json:"d"` E interface{} `json:"e"` F interface{} `json:"f"` }{} return &v }, }, { name: "typed 7 field", new: func() interface{} { v := struct { A interface{} `json:"a"` B interface{} `json:"b"` C interface{} `json:"c"` D interface{} `json:"d"` E interface{} `json:"e"` F interface{} `json:"f"` G interface{} `json:"g"` }{} return &v }, }, { name: "typed 8 field", new: func() interface{} { v := struct { A interface{} `json:"a"` B interface{} `json:"b"` C interface{} `json:"c"` D interface{} `json:"d"` E interface{} `json:"e"` F interface{} `json:"f"` G interface{} `json:"g"` H interface{} `json:"h"` }{} return &v }, }, { name: "typed 9 field", new: func() interface{} { v := struct { A interface{} `json:"a"` B interface{} `json:"b"` C interface{} `json:"c"` D interface{} `json:"d"` E interface{} `json:"e"` F interface{} `json:"f"` G interface{} `json:"g"` H interface{} `json:"h"` I interface{} `json:"i"` }{} return &v }, }, { name: "typed 10 field", new: func() interface{} { v := struct { A interface{} `json:"a"` B interface{} `json:"b"` C interface{} `json:"c"` D interface{} `json:"d"` E interface{} `json:"e"` F interface{} `json:"f"` G interface{} `json:"g"` H interface{} `json:"h"` I interface{} `json:"i"` J interface{} `json:"j"` }{} return &v }, }, { name: "typed 11 field", new: func() interface{} { v := struct { A interface{} `json:"a"` B interface{} `json:"b"` C interface{} `json:"c"` D interface{} `json:"d"` E interface{} `json:"e"` F interface{} `json:"f"` G interface{} `json:"g"` H interface{} `json:"h"` I interface{} `json:"i"` J interface{} `json:"j"` K interface{} `json:"k"` }{} return &v }, }, } for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { for _, target := range targets { t.Run(target.name, func(t *testing.T) { err := jsoniter.Unmarshal(tc.data, target.new()) if len(tc.expectError) == 0 { if err != nil { t.Errorf("unexpected error: %v", err) } } else { if err == nil { t.Errorf("expected error, got none") } else if !strings.Contains(err.Error(), tc.expectError) { t.Errorf("expected error containing '%s', got: %v", tc.expectError, err) } } }) } }) } } func Test_nested(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{"hello": [{"world": "value1"}, {"world": "value2"}]}`) l1 := Level1{} for l1Field := iter.ReadObject(); l1Field != ""; l1Field = iter.ReadObject() { switch l1Field { case "hello": l2Array := []Level2{} for iter.ReadArray() { l2 := Level2{} for l2Field := iter.ReadObject(); l2Field != ""; l2Field = iter.ReadObject() { switch l2Field { case "world": l2.World = iter.ReadString() default: iter.ReportError("bind l2", "unexpected field: "+l2Field) } } l2Array = append(l2Array, l2) } l1.Hello = l2Array default: iter.ReportError("bind l1", "unexpected field: "+l1Field) } } if !reflect.DeepEqual(l1, Level1{ Hello: []Level2{ {World: "value1"}, {World: "value2"}, }, }) { t.Fatal(l1) } } func Benchmark_jsoniter_nested(b *testing.B) { for n := 0; n < b.N; n++ { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{"hello": [{"world": "value1"}, {"world": "value2"}]}`) l1 := Level1{} for l1Field := iter.ReadObject(); l1Field != ""; l1Field = iter.ReadObject() { switch l1Field { case "hello": l1.Hello = readLevel1Hello(iter) default: iter.Skip() } } } } func readLevel1Hello(iter *jsoniter.Iterator) []Level2 { l2Array := make([]Level2, 0, 2) for iter.ReadArray() { l2 := Level2{} for l2Field := iter.ReadObject(); l2Field != ""; l2Field = iter.ReadObject() { switch l2Field { case "world": l2.World = iter.ReadString() default: iter.Skip() } } l2Array = append(l2Array, l2) } return l2Array } func Benchmark_json_nested(b *testing.B) { for n := 0; n < b.N; n++ { l1 := Level1{} json.Unmarshal([]byte(`{"hello": [{"world": "value1"}, {"world": "value2"}]}`), &l1) } } golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_null_test.go000066400000000000000000000040401420644465700261700ustar00rootroot00000000000000package misc_tests import ( "bytes" "io" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_read_null(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `null`) should.True(iter.ReadNil()) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `null`) should.Nil(iter.Read()) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `navy`) iter.Read() should.True(iter.Error != nil && iter.Error != io.EOF) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `navy`) iter.ReadNil() should.True(iter.Error != nil && iter.Error != io.EOF) } func Test_write_null(t *testing.T) { should := require.New(t) buf := &bytes.Buffer{} stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096) stream.WriteNil() stream.Flush() should.Nil(stream.Error) should.Equal("null", buf.String()) } func Test_decode_null_object_field(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[null,"a"]`) iter.ReadArray() if iter.ReadObject() != "" { t.FailNow() } iter.ReadArray() if iter.ReadString() != "a" { t.FailNow() } type TestObject struct { Field string } objs := []TestObject{} should.Nil(jsoniter.UnmarshalFromString("[null]", &objs)) should.Len(objs, 1) } func Test_decode_null_array_element(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[null,"a"]`) should.True(iter.ReadArray()) should.True(iter.ReadNil()) should.True(iter.ReadArray()) should.Equal("a", iter.ReadString()) } func Test_decode_null_string(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[null,"a"]`) should.True(iter.ReadArray()) should.Equal("", iter.ReadString()) should.True(iter.ReadArray()) should.Equal("a", iter.ReadString()) } func Test_decode_null_skip(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[null,"a"]`) iter.ReadArray() iter.Skip() iter.ReadArray() if iter.ReadString() != "a" { t.FailNow() } } golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_object_test.go000066400000000000000000000220331420644465700264660ustar00rootroot00000000000000package misc_tests import ( "bytes" "reflect" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" "strings" "time" ) func Test_empty_object(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{}`) field := iter.ReadObject() should.Equal("", field) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `{}`) iter.ReadObjectCB(func(iter *jsoniter.Iterator, field string) bool { should.FailNow("should not call") return true }) } func Test_one_field(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{"a": "stream"}`) field := iter.ReadObject() should.Equal("a", field) value := iter.ReadString() should.Equal("stream", value) field = iter.ReadObject() should.Equal("", field) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `{"a": "stream"}`) should.True(iter.ReadObjectCB(func(iter *jsoniter.Iterator, field string) bool { should.Equal("a", field) iter.Skip() return true })) } func Test_two_field(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{ "a": "stream" , "c": "d" }`) field := iter.ReadObject() should.Equal("a", field) value := iter.ReadString() should.Equal("stream", value) field = iter.ReadObject() should.Equal("c", field) value = iter.ReadString() should.Equal("d", value) field = iter.ReadObject() should.Equal("", field) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `{"field1": "1", "field2": 2}`) for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { switch field { case "field1": iter.ReadString() case "field2": iter.ReadInt64() default: iter.ReportError("bind object", "unexpected field") } } } func Test_write_object(t *testing.T) { should := require.New(t) buf := &bytes.Buffer{} stream := jsoniter.NewStream(jsoniter.Config{IndentionStep: 2}.Froze(), buf, 4096) stream.WriteObjectStart() stream.WriteObjectField("hello") stream.WriteInt(1) stream.WriteMore() stream.WriteObjectField("world") stream.WriteInt(2) stream.WriteObjectEnd() stream.Flush() should.Nil(stream.Error) should.Equal("{\n \"hello\": 1,\n \"world\": 2\n}", buf.String()) } func Test_reader_and_load_more(t *testing.T) { should := require.New(t) type TestObject struct { CreatedAt time.Time } reader := strings.NewReader(` { "agency": null, "candidateId": 0, "candidate": "Blah Blah", "bookingId": 0, "shiftId": 1, "shiftTypeId": 0, "shift": "Standard", "bonus": 0, "bonusNI": 0, "days": [], "totalHours": 27, "expenses": [], "weekEndingDateSystem": "2016-10-09", "weekEndingDateClient": "2016-10-09", "submittedAt": null, "submittedById": null, "approvedAt": "2016-10-10T18:38:04Z", "approvedById": 0, "authorisedAt": "2016-10-10T18:38:04Z", "authorisedById": 0, "invoicedAt": "2016-10-10T20:00:00Z", "revokedAt": null, "revokedById": null, "revokeReason": null, "rejectedAt": null, "rejectedById": null, "rejectReasonCode": null, "rejectReason": null, "createdAt": "2016-10-03T00:00:00Z", "updatedAt": "2016-11-09T10:26:13Z", "updatedById": null, "overrides": [], "bookingApproverId": null, "bookingApprover": null, "status": "approved" } `) decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(reader) obj := TestObject{} should.Nil(decoder.Decode(&obj)) } func Test_unmarshal_into_existing_value(t *testing.T) { should := require.New(t) type TestObject struct { Field1 int Field2 interface{} } var obj TestObject m := map[string]interface{}{} obj.Field2 = &m cfg := jsoniter.Config{UseNumber: true}.Froze() err := cfg.Unmarshal([]byte(`{"Field1":1,"Field2":{"k":"v"}}`), &obj) should.NoError(err) should.Equal(map[string]interface{}{ "k": "v", }, m) } // for issue421 func Test_unmarshal_anonymous_struct_invalid(t *testing.T) { should := require.New(t) t0 := struct { Field1 string }{} cfg := jsoniter.ConfigCompatibleWithStandardLibrary err := cfg.UnmarshalFromString(`{"Field1":`, &t0) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t0).String()) cfgCaseSensitive := jsoniter.Config{ CaseSensitive: true, }.Froze() type TestObject1 struct { Field1 struct { InnerField1 string } } t1 := TestObject1{} err = cfgCaseSensitive.UnmarshalFromString(`{"Field1":{"InnerField1"`, &t1) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t1.Field1).String()) should.Contains(err.Error(), reflect.TypeOf(t1).String()) type TestObject2 struct { Field1 int Field2 struct { InnerField1 string InnerField2 string } } t2 := TestObject2{} err = cfgCaseSensitive.UnmarshalFromString(`{"Field2":{"InnerField2"`, &t2) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t2.Field2).String()) should.Contains(err.Error(), reflect.TypeOf(t2).String()) type TestObject3 struct { Field1 int Field2 int Field3 struct { InnerField1 string InnerField2 string InnerField3 string } } t3 := TestObject3{} err = cfgCaseSensitive.UnmarshalFromString(`{"Field3":{"InnerField3"`, &t3) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t3.Field3).String()) should.Contains(err.Error(), reflect.TypeOf(t3).String()) type TestObject4 struct { Field1 int Field2 int Field3 int Field4 struct { InnerField1 string InnerField2 string InnerField3 string InnerField4 string } } t4 := TestObject4{} err = cfgCaseSensitive.UnmarshalFromString(`{"Field4":{"InnerField4"`, &t4) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t4.Field4).String()) should.Contains(err.Error(), reflect.TypeOf(t4).String()) type TestObject5 struct { Field1 int Field2 int Field3 int Field4 int Field5 struct { InnerField1 string InnerField2 string InnerField3 string InnerField4 string InnerField5 string } } t5 := TestObject5{} err = cfgCaseSensitive.UnmarshalFromString(`{"Field5":{"InnerField5"`, &t5) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t5.Field5).String()) should.Contains(err.Error(), reflect.TypeOf(t5).String()) type TestObject6 struct { Field1 int Field2 int Field3 int Field4 int Field5 int Field6 struct { InnerField1 string InnerField2 string InnerField3 string InnerField4 string InnerField5 string InnerField6 string } } t6 := TestObject6{} err = cfgCaseSensitive.UnmarshalFromString(`{"Field6":{"InnerField6"`, &t6) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t6.Field6).String()) should.Contains(err.Error(), reflect.TypeOf(t6).String()) type TestObject7 struct { Field1 int Field2 int Field3 int Field4 int Field5 int Field6 int Field7 struct { InnerField1 string InnerField2 string InnerField3 string InnerField4 string InnerField5 string InnerField6 string InnerField7 string } } t7 := TestObject7{} err = cfgCaseSensitive.UnmarshalFromString(`{"Field7":{"InnerField7"`, &t7) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t7.Field7).String()) should.Contains(err.Error(), reflect.TypeOf(t7).String()) type TestObject8 struct { Field1 int Field2 int Field3 int Field4 int Field5 int Field6 int Field7 int Field8 struct { InnerField1 string InnerField2 string InnerField3 string InnerField4 string InnerField5 string InnerField6 string InnerField7 string InnerField8 string } } t8 := TestObject8{} err = cfgCaseSensitive.UnmarshalFromString(`{"Field8":{"InnerField8"`, &t8) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t8.Field8).String()) should.Contains(err.Error(), reflect.TypeOf(t8).String()) type TestObject9 struct { Field1 int Field2 int Field3 int Field4 int Field5 int Field6 int Field7 int Field8 int Field9 struct { InnerField1 string InnerField2 string InnerField3 string InnerField4 string InnerField5 string InnerField6 string InnerField7 string InnerField8 string InnerField9 string } } t9 := TestObject9{} err = cfgCaseSensitive.UnmarshalFromString(`{"Field9":{"InnerField9"`, &t9) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t9.Field9).String()) should.Contains(err.Error(), reflect.TypeOf(t9).String()) type TestObject10 struct { Field1 int Field2 int Field3 int Field4 int Field5 int Field6 int Field7 int Field8 int Field9 int Field10 struct { InnerField1 string InnerField2 string InnerField3 string InnerField4 string InnerField5 string InnerField6 string InnerField7 string InnerField8 string InnerField9 string InnerField10 string } } t10 := TestObject10{} err = cfgCaseSensitive.UnmarshalFromString(`{"Field10":{"InnerField10"`, &t10) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t10.Field10).String()) should.Contains(err.Error(), reflect.TypeOf(t10).String()) err = cfg.UnmarshalFromString(`{"Field10":{"InnerField10"`, &t10) should.NotNil(err) should.NotContains(err.Error(), reflect.TypeOf(t10.Field10).String()) should.Contains(err.Error(), reflect.TypeOf(t10).String()) } golang-github-json-iterator-go-1.1.12/misc_tests/jsoniter_raw_message_test.go000066400000000000000000000064231420644465700275220ustar00rootroot00000000000000package misc_tests import ( "encoding/json" "github.com/json-iterator/go" "github.com/stretchr/testify/require" "strings" "testing" ) func Test_jsoniter_RawMessage(t *testing.T) { should := require.New(t) var data jsoniter.RawMessage should.Nil(jsoniter.Unmarshal([]byte(`[1,2,3]`), &data)) should.Equal(`[1,2,3]`, string(data)) str, err := jsoniter.MarshalToString(data) should.Nil(err) should.Equal(`[1,2,3]`, str) } func Test_encode_map_of_jsoniter_raw_message(t *testing.T) { should := require.New(t) type RawMap map[string]*jsoniter.RawMessage value := jsoniter.RawMessage("[]") rawMap := RawMap{"hello": &value} output, err := jsoniter.MarshalToString(rawMap) should.Nil(err) should.Equal(`{"hello":[]}`, output) } func Test_marshal_invalid_json_raw_message(t *testing.T) { type A struct { Raw json.RawMessage `json:"raw"` } message := []byte(`{}`) a := A{} should := require.New(t) should.Nil(jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(message, &a)) aout, aouterr := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&a) should.Equal(`{"raw":null}`, string(aout)) should.Nil(aouterr) } func Test_marshal_nil_json_raw_message(t *testing.T) { type A struct { Nil1 jsoniter.RawMessage `json:"raw1"` Nil2 json.RawMessage `json:"raw2"` } a := A{} should := require.New(t) aout, aouterr := jsoniter.Marshal(&a) should.Equal(`{"raw1":null,"raw2":null}`, string(aout)) should.Nil(aouterr) a.Nil1 = []byte(`Any`) a.Nil2 = []byte(`Any`) should.Nil(jsoniter.Unmarshal(aout, &a)) should.Nil(a.Nil1) should.Nil(a.Nil2) } func Test_raw_message_memory_not_copied_issue(t *testing.T) { jsonStream := `{"name":"xxxxx","bundle_id":"com.zonst.majiang","app_platform":"ios","app_category":"100103", "budget_day":1000,"bidding_min":1,"bidding_max":2,"bidding_type":"CPM", "freq":{"open":true,"type":"day","num":100},"speed":1, "targeting":{"vendor":{"open":true,"list":["zonst"]}, "geo_code":{"open":true,"list":["156110100"]},"app_category":{"open":true,"list":["100101"]}, "day_parting":{"open":true,"list":["100409","100410"]},"device_type":{"open":true,"list":["ipad"]}, "os_version":{"open":true,"list":[10]},"carrier":{"open":true,"list":["mobile"]}, "network":{"open":true,"list":["4G"]}},"url":{"tracking_imp_url":"http://www.baidu.com", "tracking_clk_url":"http://www.baidu.com","jump_url":"http://www.baidu.com","deep_link_url":"http://www.baidu.com"}}` type IteratorObject struct { Name *string `json:"name"` BundleId *string `json:"bundle_id"` AppCategory *string `json:"app_category"` AppPlatform *string `json:"app_platform"` BudgetDay *float32 `json:"budget_day"` BiddingMax *float32 `json:"bidding_max"` BiddingMin *float32 `json:"bidding_min"` BiddingType *string `json:"bidding_type"` Freq *jsoniter.RawMessage `json:"freq"` Targeting *jsoniter.RawMessage `json:"targeting"` Url *jsoniter.RawMessage `json:"url"` Speed *int `json:"speed" db:"speed"` } obj := &IteratorObject{} decoder := jsoniter.NewDecoder(strings.NewReader(jsonStream)) err := decoder.Decode(obj) should := require.New(t) should.Nil(err) should.Equal(`{"open":true,"type":"day","num":100}`, string(*obj.Freq)) } golang-github-json-iterator-go-1.1.12/pool.go000066400000000000000000000016741420644465700210500ustar00rootroot00000000000000package jsoniter import ( "io" ) // IteratorPool a thread safe pool of iterators with same configuration type IteratorPool interface { BorrowIterator(data []byte) *Iterator ReturnIterator(iter *Iterator) } // StreamPool a thread safe pool of streams with same configuration type StreamPool interface { BorrowStream(writer io.Writer) *Stream ReturnStream(stream *Stream) } func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { stream := cfg.streamPool.Get().(*Stream) stream.Reset(writer) return stream } func (cfg *frozenConfig) ReturnStream(stream *Stream) { stream.out = nil stream.Error = nil stream.Attachment = nil cfg.streamPool.Put(stream) } func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator { iter := cfg.iteratorPool.Get().(*Iterator) iter.ResetBytes(data) return iter } func (cfg *frozenConfig) ReturnIterator(iter *Iterator) { iter.Error = nil iter.Attachment = nil cfg.iteratorPool.Put(iter) } golang-github-json-iterator-go-1.1.12/reflect.go000066400000000000000000000210411420644465700215110ustar00rootroot00000000000000package 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{}) { depth := iter.depth cacheKey := reflect2.RTypeOf(obj) decoder := iter.cfg.getDecoderFromCache(cacheKey) if decoder == nil { typ := reflect2.TypeOf(obj) if typ == nil || 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) if iter.depth != depth { iter.ReportError("ReadVal", "unexpected mismatched nesting") return } } // 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) } golang-github-json-iterator-go-1.1.12/reflect_array.go000066400000000000000000000051341420644465700227140ustar00rootroot00000000000000package 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 } } golang-github-json-iterator-go-1.1.12/reflect_dynamic.go000066400000000000000000000026621420644465700232250ustar00rootroot00000000000000package 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) } golang-github-json-iterator-go-1.1.12/reflect_extension.go000066400000000000000000000343701420644465700236160ustar00rootroot00000000000000package jsoniter import ( "fmt" "github.com/modern-go/reflect2" "reflect" "sort" "strings" "unicode" "unsafe" ) var typeDecoders = map[string]ValDecoder{} var fieldDecoders = map[string]ValDecoder{} var typeEncoders = map[string]ValEncoder{} var fieldEncoders = map[string]ValEncoder{} var extensions = []Extension{} // StructDescriptor describe how should we encode/decode the struct type StructDescriptor struct { Type reflect2.Type Fields []*Binding } // GetField get one field from the descriptor by its name. // Can not use map here to keep field orders. func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding { for _, binding := range structDescriptor.Fields { if binding.Field.Name() == fieldName { return binding } } return nil } // Binding describe how should we encode/decode the struct field type Binding struct { levels []int Field reflect2.StructField FromNames []string ToNames []string Encoder ValEncoder Decoder ValDecoder } // Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder. // Can also rename fields by UpdateStructDescriptor. type Extension interface { UpdateStructDescriptor(structDescriptor *StructDescriptor) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder CreateMapKeyEncoder(typ reflect2.Type) ValEncoder CreateDecoder(typ reflect2.Type) ValDecoder CreateEncoder(typ reflect2.Type) ValEncoder DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder } // DummyExtension embed this type get dummy implementation for all methods of Extension type DummyExtension struct { } // UpdateStructDescriptor No-op func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { } // CreateMapKeyDecoder No-op func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { return nil } // CreateMapKeyEncoder No-op func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { return nil } // CreateDecoder No-op func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder { return nil } // CreateEncoder No-op func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder { return nil } // DecorateDecoder No-op func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { return decoder } // DecorateEncoder No-op func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { return encoder } type EncoderExtension map[reflect2.Type]ValEncoder // UpdateStructDescriptor No-op func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { } // CreateDecoder No-op func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { return nil } // CreateEncoder get encoder from map func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { return extension[typ] } // CreateMapKeyDecoder No-op func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { return nil } // CreateMapKeyEncoder No-op func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { return nil } // DecorateDecoder No-op func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { return decoder } // DecorateEncoder No-op func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { return encoder } type DecoderExtension map[reflect2.Type]ValDecoder // UpdateStructDescriptor No-op func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { } // CreateMapKeyDecoder No-op func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { return nil } // CreateMapKeyEncoder No-op func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { return nil } // CreateDecoder get decoder from map func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { return extension[typ] } // CreateEncoder No-op func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { return nil } // DecorateDecoder No-op func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { return decoder } // DecorateEncoder No-op func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { return encoder } type funcDecoder struct { fun DecoderFunc } func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { decoder.fun(ptr, iter) } type funcEncoder struct { fun EncoderFunc isEmptyFunc func(ptr unsafe.Pointer) bool } func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { encoder.fun(ptr, stream) } func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { if encoder.isEmptyFunc == nil { return false } return encoder.isEmptyFunc(ptr) } // DecoderFunc the function form of TypeDecoder type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) // EncoderFunc the function form of TypeEncoder type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) // RegisterTypeDecoderFunc register TypeDecoder for a type with function func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) { typeDecoders[typ] = &funcDecoder{fun} } // RegisterTypeDecoder register TypeDecoder for a typ func RegisterTypeDecoder(typ string, decoder ValDecoder) { typeDecoders[typ] = decoder } // RegisterFieldDecoderFunc register TypeDecoder for a struct field with function func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) { RegisterFieldDecoder(typ, field, &funcDecoder{fun}) } // RegisterFieldDecoder register TypeDecoder for a struct field func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) { fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder } // RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc} } // RegisterTypeEncoder register TypeEncoder for a type func RegisterTypeEncoder(typ string, encoder ValEncoder) { typeEncoders[typ] = encoder } // RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc}) } // RegisterFieldEncoder register TypeEncoder for a struct field func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) { fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder } // RegisterExtension register extension func RegisterExtension(extension Extension) { extensions = append(extensions, extension) } func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { decoder := _getTypeDecoderFromExtension(ctx, typ) if decoder != nil { for _, extension := range extensions { decoder = extension.DecorateDecoder(typ, decoder) } decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) for _, extension := range ctx.extraExtensions { decoder = extension.DecorateDecoder(typ, decoder) } } return decoder } func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { for _, extension := range extensions { decoder := extension.CreateDecoder(typ) if decoder != nil { return decoder } } decoder := ctx.decoderExtension.CreateDecoder(typ) if decoder != nil { return decoder } for _, extension := range ctx.extraExtensions { decoder := extension.CreateDecoder(typ) if decoder != nil { return decoder } } typeName := typ.String() decoder = typeDecoders[typeName] if decoder != nil { return decoder } if typ.Kind() == reflect.Ptr { ptrType := typ.(*reflect2.UnsafePtrType) decoder := typeDecoders[ptrType.Elem().String()] if decoder != nil { return &OptionalDecoder{ptrType.Elem(), decoder} } } return nil } func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { encoder := _getTypeEncoderFromExtension(ctx, typ) if encoder != nil { for _, extension := range extensions { encoder = extension.DecorateEncoder(typ, encoder) } encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) for _, extension := range ctx.extraExtensions { encoder = extension.DecorateEncoder(typ, encoder) } } return encoder } func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { for _, extension := range extensions { encoder := extension.CreateEncoder(typ) if encoder != nil { return encoder } } encoder := ctx.encoderExtension.CreateEncoder(typ) if encoder != nil { return encoder } for _, extension := range ctx.extraExtensions { encoder := extension.CreateEncoder(typ) if encoder != nil { return encoder } } typeName := typ.String() encoder = typeEncoders[typeName] if encoder != nil { return encoder } if typ.Kind() == reflect.Ptr { typePtr := typ.(*reflect2.UnsafePtrType) encoder := typeEncoders[typePtr.Elem().String()] if encoder != nil { return &OptionalEncoder{encoder} } } return nil } func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor { structType := typ.(*reflect2.UnsafeStructType) embeddedBindings := []*Binding{} bindings := []*Binding{} for i := 0; i < structType.NumField(); i++ { field := structType.Field(i) tag, hastag := field.Tag().Lookup(ctx.getTagKey()) if ctx.onlyTaggedField && !hastag && !field.Anonymous() { continue } if tag == "-" || field.Name() == "_" { continue } tagParts := strings.Split(tag, ",") if field.Anonymous() && (tag == "" || tagParts[0] == "") { if field.Type().Kind() == reflect.Struct { structDescriptor := describeStruct(ctx, field.Type()) for _, binding := range structDescriptor.Fields { binding.levels = append([]int{i}, binding.levels...) omitempty := binding.Encoder.(*structFieldEncoder).omitempty binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} binding.Decoder = &structFieldDecoder{field, binding.Decoder} embeddedBindings = append(embeddedBindings, binding) } continue } else if field.Type().Kind() == reflect.Ptr { ptrType := field.Type().(*reflect2.UnsafePtrType) if ptrType.Elem().Kind() == reflect.Struct { structDescriptor := describeStruct(ctx, ptrType.Elem()) for _, binding := range structDescriptor.Fields { binding.levels = append([]int{i}, binding.levels...) omitempty := binding.Encoder.(*structFieldEncoder).omitempty binding.Encoder = &dereferenceEncoder{binding.Encoder} binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder} binding.Decoder = &structFieldDecoder{field, binding.Decoder} embeddedBindings = append(embeddedBindings, binding) } continue } } } fieldNames := calcFieldNames(field.Name(), tagParts[0], tag) fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name()) decoder := fieldDecoders[fieldCacheKey] if decoder == nil { decoder = decoderOfType(ctx.append(field.Name()), field.Type()) } encoder := fieldEncoders[fieldCacheKey] if encoder == nil { encoder = encoderOfType(ctx.append(field.Name()), field.Type()) } binding := &Binding{ Field: field, FromNames: fieldNames, ToNames: fieldNames, Decoder: decoder, Encoder: encoder, } binding.levels = []int{i} bindings = append(bindings, binding) } return createStructDescriptor(ctx, typ, bindings, embeddedBindings) } func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { structDescriptor := &StructDescriptor{ Type: typ, Fields: bindings, } for _, extension := range extensions { extension.UpdateStructDescriptor(structDescriptor) } ctx.encoderExtension.UpdateStructDescriptor(structDescriptor) ctx.decoderExtension.UpdateStructDescriptor(structDescriptor) for _, extension := range ctx.extraExtensions { extension.UpdateStructDescriptor(structDescriptor) } processTags(structDescriptor, ctx.frozenConfig) // merge normal & embedded bindings & sort with original order allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...)) sort.Sort(allBindings) structDescriptor.Fields = allBindings return structDescriptor } type sortableBindings []*Binding func (bindings sortableBindings) Len() int { return len(bindings) } func (bindings sortableBindings) Less(i, j int) bool { left := bindings[i].levels right := bindings[j].levels k := 0 for { if left[k] < right[k] { return true } else if left[k] > right[k] { return false } k++ } } func (bindings sortableBindings) Swap(i, j int) { bindings[i], bindings[j] = bindings[j], bindings[i] } func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) { for _, binding := range structDescriptor.Fields { shouldOmitEmpty := false tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",") for _, tagPart := range tagParts[1:] { if tagPart == "omitempty" { shouldOmitEmpty = true } else if tagPart == "string" { if binding.Field.Type().Kind() == reflect.String { binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg} binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg} } else { binding.Decoder = &stringModeNumberDecoder{binding.Decoder} binding.Encoder = &stringModeNumberEncoder{binding.Encoder} } } } binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder} binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty} } } func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string { // ignore? if wholeTag == "-" { return []string{} } // rename? var fieldNames []string if tagProvidedFieldName == "" { fieldNames = []string{originalFieldName} } else { fieldNames = []string{tagProvidedFieldName} } // private? isNotExported := unicode.IsLower(rune(originalFieldName[0])) || originalFieldName[0] == '_' if isNotExported { fieldNames = []string{} } return fieldNames } golang-github-json-iterator-go-1.1.12/reflect_json_number.go000066400000000000000000000052061420644465700241170ustar00rootroot00000000000000package 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 } golang-github-json-iterator-go-1.1.12/reflect_json_raw_message.go000066400000000000000000000034621420644465700251260ustar00rootroot00000000000000package 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) { if iter.ReadNil() { *((*json.RawMessage)(ptr)) = nil } else { *((*json.RawMessage)(ptr)) = iter.SkipAndReturnBytes() } } func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { if *((*json.RawMessage)(ptr)) == nil { stream.WriteNil() } else { 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) { if iter.ReadNil() { *((*RawMessage)(ptr)) = nil } else { *((*RawMessage)(ptr)) = iter.SkipAndReturnBytes() } } func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { if *((*RawMessage)(ptr)) == nil { stream.WriteNil() } else { stream.WriteRaw(string(*((*RawMessage)(ptr)))) } } func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { return len(*((*RawMessage)(ptr))) == 0 } golang-github-json-iterator-go-1.1.12/reflect_map.go000066400000000000000000000217121420644465700223530ustar00rootroot00000000000000package 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 } } ptrType := reflect2.PtrTo(typ) if ptrType.Implements(unmarshalerType) { return &referenceDecoder{ &unmarshalerDecoder{ valType: ptrType, }, } } if typ.Implements(unmarshalerType) { return &unmarshalerDecoder{ valType: typ, } } if ptrType.Implements(textUnmarshalerType) { return &referenceDecoder{ &textUnmarshalerDecoder{ valType: ptrType, }, } } if typ.Implements(textUnmarshalerType) { return &textUnmarshalerDecoder{ valType: typ, } } 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: 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 } } if typ == textMarshalerType { return &directTextMarshalerEncoder{ stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), } } if typ.Implements(textMarshalerType) { return &textMarshalerEncoder{ valType: typ, stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), } } 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.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 } 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) { if *(*unsafe.Pointer)(ptr) == nil { stream.WriteNil() return } 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) subStream.Attachment = stream.Attachment subIter := stream.cfg.BorrowIterator(nil) keyValues := encodedKeyValues{} for mapIter.HasNext() { key, elem := mapIter.UnsafeNext() subStreamIndex := subStream.Buffered() encoder.keyEncoder.Encode(key, subStream) if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil { stream.Error = subStream.Error } encodedKey := subStream.Buffer()[subStreamIndex:] 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()[subStreamIndex:], }) } sort.Sort(keyValues) for i, keyValue := range keyValues { if i != 0 { stream.WriteMore() } stream.Write(keyValue.keyValue) } if subStream.Error != nil && stream.Error == nil { stream.Error = subStream.Error } 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 } golang-github-json-iterator-go-1.1.12/reflect_marshaler.go000066400000000000000000000135141420644465700235550ustar00rootroot00000000000000package jsoniter import ( "encoding" "encoding/json" "unsafe" "github.com/modern-go/reflect2" ) 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 { // html escape was already done by jsoniter // but the extra '\n' should be trimed l := len(bytes) if l > 0 && bytes[l-1] == '\n' { bytes = bytes[:l-1] } 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()) } } golang-github-json-iterator-go-1.1.12/reflect_native.go000066400000000000000000000256211420644465700230670ustar00rootroot00000000000000package 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) { if codec.sliceType.UnsafeIsNil(ptr) { stream.WriteNil() return } src := *((*[]byte)(ptr)) encoding := base64.StdEncoding stream.writeByte('"') if len(src) != 0 { 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 } golang-github-json-iterator-go-1.1.12/reflect_optional.go000066400000000000000000000064551420644465700234320ustar00rootroot00000000000000package jsoniter import ( "github.com/modern-go/reflect2" "unsafe" ) func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder { ptrType := typ.(*reflect2.UnsafePtrType) elemType := ptrType.Elem() decoder := decoderOfType(ctx, elemType) 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) } golang-github-json-iterator-go-1.1.12/reflect_slice.go000066400000000000000000000051461420644465700227000ustar00rootroot00000000000000package 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 } } golang-github-json-iterator-go-1.1.12/reflect_struct_decoder.go000066400000000000000000000724431420644465700246160ustar00rootroot00000000000000package jsoniter import ( "fmt" "io" "strings" "unsafe" "github.com/modern-go/reflect2" ) func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder { bindings := map[string]*Binding{} structDescriptor := describeStruct(ctx, typ) for _, binding := range structDescriptor.Fields { for _, fromName := range binding.FromNames { old := bindings[fromName] if old == nil { bindings[fromName] = binding continue } ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding) if ignoreOld { delete(bindings, fromName) } if !ignoreNew { bindings[fromName] = binding } } } fields := map[string]*structFieldDecoder{} for k, binding := range bindings { fields[k] = binding.Decoder.(*structFieldDecoder) } if !ctx.caseSensitive() { for k, binding := range bindings { if _, found := fields[strings.ToLower(k)]; !found { fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder) } } } return createStructDecoder(ctx, typ, fields) } func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder { if ctx.disallowUnknownFields { return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true} } knownHash := map[int64]struct{}{ 0: {}, } switch len(fields) { case 0: return &skipObjectDecoder{typ} case 1: for fieldName, fieldDecoder := range fields { fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder} } case 2: var fieldHash1 int64 var fieldHash2 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder for fieldName, fieldDecoder := range fields { fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldHash1 == 0 { fieldHash1 = fieldHash fieldDecoder1 = fieldDecoder } else { fieldHash2 = fieldHash fieldDecoder2 = fieldDecoder } } return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2} case 3: var fieldName1 int64 var fieldName2 int64 var fieldName3 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder for fieldName, fieldDecoder := range fields { fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { fieldName1 = fieldHash fieldDecoder1 = fieldDecoder } else if fieldName2 == 0 { fieldName2 = fieldHash fieldDecoder2 = fieldDecoder } else { fieldName3 = fieldHash fieldDecoder3 = fieldDecoder } } return &threeFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3} case 4: var fieldName1 int64 var fieldName2 int64 var fieldName3 int64 var fieldName4 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder var fieldDecoder4 *structFieldDecoder for fieldName, fieldDecoder := range fields { fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { fieldName1 = fieldHash fieldDecoder1 = fieldDecoder } else if fieldName2 == 0 { fieldName2 = fieldHash fieldDecoder2 = fieldDecoder } else if fieldName3 == 0 { fieldName3 = fieldHash fieldDecoder3 = fieldDecoder } else { fieldName4 = fieldHash fieldDecoder4 = fieldDecoder } } return &fourFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, fieldName4, fieldDecoder4} case 5: var fieldName1 int64 var fieldName2 int64 var fieldName3 int64 var fieldName4 int64 var fieldName5 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder var fieldDecoder4 *structFieldDecoder var fieldDecoder5 *structFieldDecoder for fieldName, fieldDecoder := range fields { fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { fieldName1 = fieldHash fieldDecoder1 = fieldDecoder } else if fieldName2 == 0 { fieldName2 = fieldHash fieldDecoder2 = fieldDecoder } else if fieldName3 == 0 { fieldName3 = fieldHash fieldDecoder3 = fieldDecoder } else if fieldName4 == 0 { fieldName4 = fieldHash fieldDecoder4 = fieldDecoder } else { fieldName5 = fieldHash fieldDecoder5 = fieldDecoder } } return &fiveFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, fieldName4, fieldDecoder4, fieldName5, fieldDecoder5} case 6: var fieldName1 int64 var fieldName2 int64 var fieldName3 int64 var fieldName4 int64 var fieldName5 int64 var fieldName6 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder var fieldDecoder4 *structFieldDecoder var fieldDecoder5 *structFieldDecoder var fieldDecoder6 *structFieldDecoder for fieldName, fieldDecoder := range fields { fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { fieldName1 = fieldHash fieldDecoder1 = fieldDecoder } else if fieldName2 == 0 { fieldName2 = fieldHash fieldDecoder2 = fieldDecoder } else if fieldName3 == 0 { fieldName3 = fieldHash fieldDecoder3 = fieldDecoder } else if fieldName4 == 0 { fieldName4 = fieldHash fieldDecoder4 = fieldDecoder } else if fieldName5 == 0 { fieldName5 = fieldHash fieldDecoder5 = fieldDecoder } else { fieldName6 = fieldHash fieldDecoder6 = fieldDecoder } } return &sixFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6} case 7: var fieldName1 int64 var fieldName2 int64 var fieldName3 int64 var fieldName4 int64 var fieldName5 int64 var fieldName6 int64 var fieldName7 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder var fieldDecoder4 *structFieldDecoder var fieldDecoder5 *structFieldDecoder var fieldDecoder6 *structFieldDecoder var fieldDecoder7 *structFieldDecoder for fieldName, fieldDecoder := range fields { fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { fieldName1 = fieldHash fieldDecoder1 = fieldDecoder } else if fieldName2 == 0 { fieldName2 = fieldHash fieldDecoder2 = fieldDecoder } else if fieldName3 == 0 { fieldName3 = fieldHash fieldDecoder3 = fieldDecoder } else if fieldName4 == 0 { fieldName4 = fieldHash fieldDecoder4 = fieldDecoder } else if fieldName5 == 0 { fieldName5 = fieldHash fieldDecoder5 = fieldDecoder } else if fieldName6 == 0 { fieldName6 = fieldHash fieldDecoder6 = fieldDecoder } else { fieldName7 = fieldHash fieldDecoder7 = fieldDecoder } } return &sevenFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, fieldName7, fieldDecoder7} case 8: var fieldName1 int64 var fieldName2 int64 var fieldName3 int64 var fieldName4 int64 var fieldName5 int64 var fieldName6 int64 var fieldName7 int64 var fieldName8 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder var fieldDecoder4 *structFieldDecoder var fieldDecoder5 *structFieldDecoder var fieldDecoder6 *structFieldDecoder var fieldDecoder7 *structFieldDecoder var fieldDecoder8 *structFieldDecoder for fieldName, fieldDecoder := range fields { fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { fieldName1 = fieldHash fieldDecoder1 = fieldDecoder } else if fieldName2 == 0 { fieldName2 = fieldHash fieldDecoder2 = fieldDecoder } else if fieldName3 == 0 { fieldName3 = fieldHash fieldDecoder3 = fieldDecoder } else if fieldName4 == 0 { fieldName4 = fieldHash fieldDecoder4 = fieldDecoder } else if fieldName5 == 0 { fieldName5 = fieldHash fieldDecoder5 = fieldDecoder } else if fieldName6 == 0 { fieldName6 = fieldHash fieldDecoder6 = fieldDecoder } else if fieldName7 == 0 { fieldName7 = fieldHash fieldDecoder7 = fieldDecoder } else { fieldName8 = fieldHash fieldDecoder8 = fieldDecoder } } return &eightFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, fieldName7, fieldDecoder7, fieldName8, fieldDecoder8} case 9: var fieldName1 int64 var fieldName2 int64 var fieldName3 int64 var fieldName4 int64 var fieldName5 int64 var fieldName6 int64 var fieldName7 int64 var fieldName8 int64 var fieldName9 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder var fieldDecoder4 *structFieldDecoder var fieldDecoder5 *structFieldDecoder var fieldDecoder6 *structFieldDecoder var fieldDecoder7 *structFieldDecoder var fieldDecoder8 *structFieldDecoder var fieldDecoder9 *structFieldDecoder for fieldName, fieldDecoder := range fields { fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { fieldName1 = fieldHash fieldDecoder1 = fieldDecoder } else if fieldName2 == 0 { fieldName2 = fieldHash fieldDecoder2 = fieldDecoder } else if fieldName3 == 0 { fieldName3 = fieldHash fieldDecoder3 = fieldDecoder } else if fieldName4 == 0 { fieldName4 = fieldHash fieldDecoder4 = fieldDecoder } else if fieldName5 == 0 { fieldName5 = fieldHash fieldDecoder5 = fieldDecoder } else if fieldName6 == 0 { fieldName6 = fieldHash fieldDecoder6 = fieldDecoder } else if fieldName7 == 0 { fieldName7 = fieldHash fieldDecoder7 = fieldDecoder } else if fieldName8 == 0 { fieldName8 = fieldHash fieldDecoder8 = fieldDecoder } else { fieldName9 = fieldHash fieldDecoder9 = fieldDecoder } } return &nineFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9} case 10: var fieldName1 int64 var fieldName2 int64 var fieldName3 int64 var fieldName4 int64 var fieldName5 int64 var fieldName6 int64 var fieldName7 int64 var fieldName8 int64 var fieldName9 int64 var fieldName10 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder var fieldDecoder4 *structFieldDecoder var fieldDecoder5 *structFieldDecoder var fieldDecoder6 *structFieldDecoder var fieldDecoder7 *structFieldDecoder var fieldDecoder8 *structFieldDecoder var fieldDecoder9 *structFieldDecoder var fieldDecoder10 *structFieldDecoder for fieldName, fieldDecoder := range fields { fieldHash := calcHash(fieldName, ctx.caseSensitive()) _, known := knownHash[fieldHash] if known { return &generalStructDecoder{typ, fields, false} } knownHash[fieldHash] = struct{}{} if fieldName1 == 0 { fieldName1 = fieldHash fieldDecoder1 = fieldDecoder } else if fieldName2 == 0 { fieldName2 = fieldHash fieldDecoder2 = fieldDecoder } else if fieldName3 == 0 { fieldName3 = fieldHash fieldDecoder3 = fieldDecoder } else if fieldName4 == 0 { fieldName4 = fieldHash fieldDecoder4 = fieldDecoder } else if fieldName5 == 0 { fieldName5 = fieldHash fieldDecoder5 = fieldDecoder } else if fieldName6 == 0 { fieldName6 = fieldHash fieldDecoder6 = fieldDecoder } else if fieldName7 == 0 { fieldName7 = fieldHash fieldDecoder7 = fieldDecoder } else if fieldName8 == 0 { fieldName8 = fieldHash fieldDecoder8 = fieldDecoder } else if fieldName9 == 0 { fieldName9 = fieldHash fieldDecoder9 = fieldDecoder } else { fieldName10 = fieldHash fieldDecoder10 = fieldDecoder } } return &tenFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9, fieldName10, fieldDecoder10} } return &generalStructDecoder{typ, fields, false} } type generalStructDecoder struct { typ reflect2.Type fields map[string]*structFieldDecoder disallowUnknownFields bool } func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } var c byte for c = ','; c == ','; c = iter.nextToken() { decoder.decodeOneField(ptr, iter) } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } if c != '}' { iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c})) } iter.decrementDepth() } func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) { var field string var fieldDecoder *structFieldDecoder if iter.cfg.objectFieldMustBeSimpleString { fieldBytes := iter.ReadStringAsSlice() field = *(*string)(unsafe.Pointer(&fieldBytes)) fieldDecoder = decoder.fields[field] if fieldDecoder == nil && !iter.cfg.caseSensitive { fieldDecoder = decoder.fields[strings.ToLower(field)] } } else { field = iter.ReadString() fieldDecoder = decoder.fields[field] if fieldDecoder == nil && !iter.cfg.caseSensitive { fieldDecoder = decoder.fields[strings.ToLower(field)] } } if fieldDecoder == nil { if decoder.disallowUnknownFields { msg := "found unknown field: " + field iter.ReportError("ReadObject", msg) } c := iter.nextToken() if c != ':' { iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) } iter.Skip() return } c := iter.nextToken() if c != ':' { iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) } fieldDecoder.Decode(ptr, iter) } type skipObjectDecoder struct { typ reflect2.Type } func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { valueType := iter.WhatIsNext() if valueType != ObjectValue && valueType != NilValue { iter.ReportError("skipObjectDecoder", "expect object or null") return } iter.Skip() } type oneFieldStructDecoder struct { typ reflect2.Type fieldHash int64 fieldDecoder *structFieldDecoder } func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } for { if iter.readFieldHash() == decoder.fieldHash { decoder.fieldDecoder.Decode(ptr, iter) } else { iter.Skip() } if iter.isObjectEnd() { break } } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } iter.decrementDepth() } type twoFieldsStructDecoder struct { typ reflect2.Type fieldHash1 int64 fieldDecoder1 *structFieldDecoder fieldHash2 int64 fieldDecoder2 *structFieldDecoder } func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } for { switch iter.readFieldHash() { case decoder.fieldHash1: decoder.fieldDecoder1.Decode(ptr, iter) case decoder.fieldHash2: decoder.fieldDecoder2.Decode(ptr, iter) default: iter.Skip() } if iter.isObjectEnd() { break } } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } iter.decrementDepth() } type threeFieldsStructDecoder struct { typ reflect2.Type fieldHash1 int64 fieldDecoder1 *structFieldDecoder fieldHash2 int64 fieldDecoder2 *structFieldDecoder fieldHash3 int64 fieldDecoder3 *structFieldDecoder } func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } for { switch iter.readFieldHash() { case decoder.fieldHash1: decoder.fieldDecoder1.Decode(ptr, iter) case decoder.fieldHash2: decoder.fieldDecoder2.Decode(ptr, iter) case decoder.fieldHash3: decoder.fieldDecoder3.Decode(ptr, iter) default: iter.Skip() } if iter.isObjectEnd() { break } } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } iter.decrementDepth() } type fourFieldsStructDecoder struct { typ reflect2.Type fieldHash1 int64 fieldDecoder1 *structFieldDecoder fieldHash2 int64 fieldDecoder2 *structFieldDecoder fieldHash3 int64 fieldDecoder3 *structFieldDecoder fieldHash4 int64 fieldDecoder4 *structFieldDecoder } func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } for { switch iter.readFieldHash() { case decoder.fieldHash1: decoder.fieldDecoder1.Decode(ptr, iter) case decoder.fieldHash2: decoder.fieldDecoder2.Decode(ptr, iter) case decoder.fieldHash3: decoder.fieldDecoder3.Decode(ptr, iter) case decoder.fieldHash4: decoder.fieldDecoder4.Decode(ptr, iter) default: iter.Skip() } if iter.isObjectEnd() { break } } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } iter.decrementDepth() } type fiveFieldsStructDecoder struct { typ reflect2.Type fieldHash1 int64 fieldDecoder1 *structFieldDecoder fieldHash2 int64 fieldDecoder2 *structFieldDecoder fieldHash3 int64 fieldDecoder3 *structFieldDecoder fieldHash4 int64 fieldDecoder4 *structFieldDecoder fieldHash5 int64 fieldDecoder5 *structFieldDecoder } func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } for { switch iter.readFieldHash() { case decoder.fieldHash1: decoder.fieldDecoder1.Decode(ptr, iter) case decoder.fieldHash2: decoder.fieldDecoder2.Decode(ptr, iter) case decoder.fieldHash3: decoder.fieldDecoder3.Decode(ptr, iter) case decoder.fieldHash4: decoder.fieldDecoder4.Decode(ptr, iter) case decoder.fieldHash5: decoder.fieldDecoder5.Decode(ptr, iter) default: iter.Skip() } if iter.isObjectEnd() { break } } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } iter.decrementDepth() } type sixFieldsStructDecoder struct { typ reflect2.Type fieldHash1 int64 fieldDecoder1 *structFieldDecoder fieldHash2 int64 fieldDecoder2 *structFieldDecoder fieldHash3 int64 fieldDecoder3 *structFieldDecoder fieldHash4 int64 fieldDecoder4 *structFieldDecoder fieldHash5 int64 fieldDecoder5 *structFieldDecoder fieldHash6 int64 fieldDecoder6 *structFieldDecoder } func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } for { switch iter.readFieldHash() { case decoder.fieldHash1: decoder.fieldDecoder1.Decode(ptr, iter) case decoder.fieldHash2: decoder.fieldDecoder2.Decode(ptr, iter) case decoder.fieldHash3: decoder.fieldDecoder3.Decode(ptr, iter) case decoder.fieldHash4: decoder.fieldDecoder4.Decode(ptr, iter) case decoder.fieldHash5: decoder.fieldDecoder5.Decode(ptr, iter) case decoder.fieldHash6: decoder.fieldDecoder6.Decode(ptr, iter) default: iter.Skip() } if iter.isObjectEnd() { break } } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } iter.decrementDepth() } type sevenFieldsStructDecoder struct { typ reflect2.Type fieldHash1 int64 fieldDecoder1 *structFieldDecoder fieldHash2 int64 fieldDecoder2 *structFieldDecoder fieldHash3 int64 fieldDecoder3 *structFieldDecoder fieldHash4 int64 fieldDecoder4 *structFieldDecoder fieldHash5 int64 fieldDecoder5 *structFieldDecoder fieldHash6 int64 fieldDecoder6 *structFieldDecoder fieldHash7 int64 fieldDecoder7 *structFieldDecoder } func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } for { switch iter.readFieldHash() { case decoder.fieldHash1: decoder.fieldDecoder1.Decode(ptr, iter) case decoder.fieldHash2: decoder.fieldDecoder2.Decode(ptr, iter) case decoder.fieldHash3: decoder.fieldDecoder3.Decode(ptr, iter) case decoder.fieldHash4: decoder.fieldDecoder4.Decode(ptr, iter) case decoder.fieldHash5: decoder.fieldDecoder5.Decode(ptr, iter) case decoder.fieldHash6: decoder.fieldDecoder6.Decode(ptr, iter) case decoder.fieldHash7: decoder.fieldDecoder7.Decode(ptr, iter) default: iter.Skip() } if iter.isObjectEnd() { break } } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } iter.decrementDepth() } type eightFieldsStructDecoder struct { typ reflect2.Type fieldHash1 int64 fieldDecoder1 *structFieldDecoder fieldHash2 int64 fieldDecoder2 *structFieldDecoder fieldHash3 int64 fieldDecoder3 *structFieldDecoder fieldHash4 int64 fieldDecoder4 *structFieldDecoder fieldHash5 int64 fieldDecoder5 *structFieldDecoder fieldHash6 int64 fieldDecoder6 *structFieldDecoder fieldHash7 int64 fieldDecoder7 *structFieldDecoder fieldHash8 int64 fieldDecoder8 *structFieldDecoder } func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } for { switch iter.readFieldHash() { case decoder.fieldHash1: decoder.fieldDecoder1.Decode(ptr, iter) case decoder.fieldHash2: decoder.fieldDecoder2.Decode(ptr, iter) case decoder.fieldHash3: decoder.fieldDecoder3.Decode(ptr, iter) case decoder.fieldHash4: decoder.fieldDecoder4.Decode(ptr, iter) case decoder.fieldHash5: decoder.fieldDecoder5.Decode(ptr, iter) case decoder.fieldHash6: decoder.fieldDecoder6.Decode(ptr, iter) case decoder.fieldHash7: decoder.fieldDecoder7.Decode(ptr, iter) case decoder.fieldHash8: decoder.fieldDecoder8.Decode(ptr, iter) default: iter.Skip() } if iter.isObjectEnd() { break } } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } iter.decrementDepth() } type nineFieldsStructDecoder struct { typ reflect2.Type fieldHash1 int64 fieldDecoder1 *structFieldDecoder fieldHash2 int64 fieldDecoder2 *structFieldDecoder fieldHash3 int64 fieldDecoder3 *structFieldDecoder fieldHash4 int64 fieldDecoder4 *structFieldDecoder fieldHash5 int64 fieldDecoder5 *structFieldDecoder fieldHash6 int64 fieldDecoder6 *structFieldDecoder fieldHash7 int64 fieldDecoder7 *structFieldDecoder fieldHash8 int64 fieldDecoder8 *structFieldDecoder fieldHash9 int64 fieldDecoder9 *structFieldDecoder } func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } for { switch iter.readFieldHash() { case decoder.fieldHash1: decoder.fieldDecoder1.Decode(ptr, iter) case decoder.fieldHash2: decoder.fieldDecoder2.Decode(ptr, iter) case decoder.fieldHash3: decoder.fieldDecoder3.Decode(ptr, iter) case decoder.fieldHash4: decoder.fieldDecoder4.Decode(ptr, iter) case decoder.fieldHash5: decoder.fieldDecoder5.Decode(ptr, iter) case decoder.fieldHash6: decoder.fieldDecoder6.Decode(ptr, iter) case decoder.fieldHash7: decoder.fieldDecoder7.Decode(ptr, iter) case decoder.fieldHash8: decoder.fieldDecoder8.Decode(ptr, iter) case decoder.fieldHash9: decoder.fieldDecoder9.Decode(ptr, iter) default: iter.Skip() } if iter.isObjectEnd() { break } } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } iter.decrementDepth() } type tenFieldsStructDecoder struct { typ reflect2.Type fieldHash1 int64 fieldDecoder1 *structFieldDecoder fieldHash2 int64 fieldDecoder2 *structFieldDecoder fieldHash3 int64 fieldDecoder3 *structFieldDecoder fieldHash4 int64 fieldDecoder4 *structFieldDecoder fieldHash5 int64 fieldDecoder5 *structFieldDecoder fieldHash6 int64 fieldDecoder6 *structFieldDecoder fieldHash7 int64 fieldDecoder7 *structFieldDecoder fieldHash8 int64 fieldDecoder8 *structFieldDecoder fieldHash9 int64 fieldDecoder9 *structFieldDecoder fieldHash10 int64 fieldDecoder10 *structFieldDecoder } func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if !iter.readObjectStart() { return } if !iter.incrementDepth() { return } for { switch iter.readFieldHash() { case decoder.fieldHash1: decoder.fieldDecoder1.Decode(ptr, iter) case decoder.fieldHash2: decoder.fieldDecoder2.Decode(ptr, iter) case decoder.fieldHash3: decoder.fieldDecoder3.Decode(ptr, iter) case decoder.fieldHash4: decoder.fieldDecoder4.Decode(ptr, iter) case decoder.fieldHash5: decoder.fieldDecoder5.Decode(ptr, iter) case decoder.fieldHash6: decoder.fieldDecoder6.Decode(ptr, iter) case decoder.fieldHash7: decoder.fieldDecoder7.Decode(ptr, iter) case decoder.fieldHash8: decoder.fieldDecoder8.Decode(ptr, iter) case decoder.fieldHash9: decoder.fieldDecoder9.Decode(ptr, iter) case decoder.fieldHash10: decoder.fieldDecoder10.Decode(ptr, iter) default: iter.Skip() } if iter.isObjectEnd() { break } } if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } iter.decrementDepth() } type structFieldDecoder struct { field reflect2.StructField fieldDecoder ValDecoder } func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { fieldPtr := decoder.field.UnsafeGet(ptr) decoder.fieldDecoder.Decode(fieldPtr, iter) if iter.Error != nil && iter.Error != io.EOF { iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error()) } } type stringModeStringDecoder struct { elemDecoder ValDecoder cfg *frozenConfig } func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { decoder.elemDecoder.Decode(ptr, iter) str := *((*string)(ptr)) tempIter := decoder.cfg.BorrowIterator([]byte(str)) defer decoder.cfg.ReturnIterator(tempIter) *((*string)(ptr)) = tempIter.ReadString() } type stringModeNumberDecoder struct { elemDecoder ValDecoder } func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if iter.WhatIsNext() == NilValue { decoder.elemDecoder.Decode(ptr, iter) return } 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 } } golang-github-json-iterator-go-1.1.12/reflect_struct_encoder.go000066400000000000000000000122571420644465700246250ustar00rootroot00000000000000package jsoniter import ( "fmt" "github.com/modern-go/reflect2" "io" "reflect" "unsafe" ) func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder { type bindingTo struct { binding *Binding toName string ignored bool } orderedBindings := []*bindingTo{} structDescriptor := describeStruct(ctx, typ) for _, binding := range structDescriptor.Fields { for _, toName := range binding.ToNames { new := &bindingTo{ binding: binding, toName: toName, } for _, old := range orderedBindings { if old.toName != toName { continue } old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding) } orderedBindings = append(orderedBindings, new) } } if len(orderedBindings) == 0 { return &emptyStructEncoder{} } finalOrderedFields := []structFieldTo{} for _, bindingTo := range orderedBindings { if !bindingTo.ignored { finalOrderedFields = append(finalOrderedFields, structFieldTo{ encoder: bindingTo.binding.Encoder.(*structFieldEncoder), toName: bindingTo.toName, }) } } return &structEncoder{typ, finalOrderedFields} } func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty { encoder := createEncoderOfNative(ctx, typ) if encoder != nil { return encoder } kind := typ.Kind() switch kind { case reflect.Interface: return &dynamicEncoder{typ} case reflect.Struct: return &structEncoder{typ: typ} case reflect.Array: return &arrayEncoder{} case reflect.Slice: return &sliceEncoder{} case reflect.Map: return encoderOfMap(ctx, typ) case reflect.Ptr: return &OptionalEncoder{} default: return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)} } } func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) { newTagged := new.Field.Tag().Get(cfg.getTagKey()) != "" oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != "" if newTagged { if oldTagged { if len(old.levels) > len(new.levels) { return true, false } else if len(new.levels) > len(old.levels) { return false, true } else { return true, true } } else { return true, false } } else { if oldTagged { return true, false } if len(old.levels) > len(new.levels) { return true, false } else if len(new.levels) > len(old.levels) { return false, true } else { return true, true } } } type structFieldEncoder struct { field reflect2.StructField fieldEncoder ValEncoder omitempty bool } func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { fieldPtr := encoder.field.UnsafeGet(ptr) encoder.fieldEncoder.Encode(fieldPtr, stream) if stream.Error != nil && stream.Error != io.EOF { stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error()) } } func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool { fieldPtr := encoder.field.UnsafeGet(ptr) return encoder.fieldEncoder.IsEmpty(fieldPtr) } func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil) if !converted { return false } fieldPtr := encoder.field.UnsafeGet(ptr) return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) } type IsEmbeddedPtrNil interface { IsEmbeddedPtrNil(ptr unsafe.Pointer) bool } type structEncoder struct { typ reflect2.Type fields []structFieldTo } type structFieldTo struct { encoder *structFieldEncoder toName string } func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { stream.WriteObjectStart() isNotFirst := false for _, field := range encoder.fields { if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { continue } if field.encoder.IsEmbeddedPtrNil(ptr) { continue } if isNotFirst { stream.WriteMore() } stream.WriteObjectField(field.toName) field.encoder.Encode(ptr, stream) isNotFirst = true } stream.WriteObjectEnd() if stream.Error != nil && stream.Error != io.EOF { stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error()) } } func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool { return false } type emptyStructEncoder struct { } func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { stream.WriteEmptyObject() } func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool { return false } type stringModeNumberEncoder struct { elemEncoder ValEncoder } func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { stream.writeByte('"') encoder.elemEncoder.Encode(ptr, stream) stream.writeByte('"') } func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool { return encoder.elemEncoder.IsEmpty(ptr) } type stringModeStringEncoder struct { elemEncoder ValEncoder cfg *frozenConfig } func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { tempStream := encoder.cfg.BorrowStream(nil) tempStream.Attachment = stream.Attachment 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) } golang-github-json-iterator-go-1.1.12/skip_tests/000077500000000000000000000000001420644465700217305ustar00rootroot00000000000000golang-github-json-iterator-go-1.1.12/skip_tests/array_test.go000066400000000000000000000005021420644465700244310ustar00rootroot00000000000000package skip_tests func init() { testCases = append(testCases, testCase{ ptr: (*[]interface{})(nil), inputs: []string{ `[]`, // valid `[1]`, // valid `[ 1, "hello"]`, // valid `[abc]`, // invalid `[`, // invalid `[[]`, // invalid }, }) } golang-github-json-iterator-go-1.1.12/skip_tests/float64_test.go000066400000000000000000000006261420644465700246010ustar00rootroot00000000000000package skip_tests func init() { testCases = append(testCases, testCase{ ptr: (*float64)(nil), inputs: []string{ "+1", // invalid "-a", // invalid "-\x00", // invalid, zero byte "0.1", // valid "0..1", // invalid, more dot "1e+1", // valid "1+1", // invalid "1E1", // valid, e or E "1ee1", // invalid "100a", // invalid "10.", // invalid }, }) } golang-github-json-iterator-go-1.1.12/skip_tests/jsoniter_skip_test.go000066400000000000000000000112231420644465700262000ustar00rootroot00000000000000package skip_tests import ( "bytes" "encoding/json" "testing" "github.com/json-iterator/go" "github.com/stretchr/testify/require" ) func Test_skip_number_in_array(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[-0.12, "stream"]`) iter.ReadArray() iter.Skip() iter.ReadArray() should.Nil(iter.Error) should.Equal("stream", iter.ReadString()) } func Test_skip_string_in_array(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `["hello", "stream"]`) iter.ReadArray() iter.Skip() iter.ReadArray() should.Nil(iter.Error) should.Equal("stream", iter.ReadString()) } func Test_skip_null(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[null , "stream"]`) iter.ReadArray() iter.Skip() iter.ReadArray() if iter.ReadString() != "stream" { t.FailNow() } } func Test_skip_true(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[true , "stream"]`) iter.ReadArray() iter.Skip() iter.ReadArray() if iter.ReadString() != "stream" { t.FailNow() } } func Test_skip_false(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[false , "stream"]`) iter.ReadArray() iter.Skip() iter.ReadArray() if iter.ReadString() != "stream" { t.FailNow() } } func Test_skip_array(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[[1, [2, [3], 4]], "stream"]`) iter.ReadArray() iter.Skip() iter.ReadArray() if iter.ReadString() != "stream" { t.FailNow() } } func Test_skip_empty_array(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[ [ ], "stream"]`) iter.ReadArray() iter.Skip() iter.ReadArray() if iter.ReadString() != "stream" { t.FailNow() } } func Test_skip_nested(t *testing.T) { iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[ {"a" : [{"stream": "c"}], "d": 102 }, "stream"]`) iter.ReadArray() iter.Skip() iter.ReadArray() if iter.ReadString() != "stream" { t.FailNow() } } func Test_skip_and_return_bytes(t *testing.T) { should := require.New(t) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[ {"a" : [{"stream": "c"}], "d": 102 }, "stream"]`) iter.ReadArray() skipped := iter.SkipAndReturnBytes() should.Equal(`{"a" : [{"stream": "c"}], "d": 102 }`, string(skipped)) } func Test_skip_and_return_bytes_with_reader(t *testing.T) { should := require.New(t) iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(`[ {"a" : [{"stream": "c"}], "d": 102 }, "stream"]`), 4) iter.ReadArray() skipped := iter.SkipAndReturnBytes() should.Equal(`{"a" : [{"stream": "c"}], "d": 102 }`, string(skipped)) } func Test_append_skip_and_return_bytes_with_reader(t *testing.T) { should := require.New(t) iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(`[ {"a" : [{"stream": "c"}], "d": 102 }, "stream"]`), 4) iter.ReadArray() buf := make([]byte, 0, 1024) buf = iter.SkipAndAppendBytes(buf) should.Equal(`{"a" : [{"stream": "c"}], "d": 102 }`, string(buf)) } func Test_skip_empty(t *testing.T) { should := require.New(t) should.NotNil(jsoniter.Get([]byte("")).LastError()) } type TestResp struct { Code uint64 } func Benchmark_jsoniter_skip(b *testing.B) { input := []byte(` { "_shards":{ "total" : 5, "successful" : 5, "failed" : 0 }, "hits":{ "total" : 1, "hits" : [ { "_index" : "twitter", "_type" : "tweet", "_id" : "1", "_source" : { "user" : "kimchy", "postDate" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" } } ] }, "code": 200 }`) for n := 0; n < b.N; n++ { result := TestResp{} iter := jsoniter.ParseBytes(jsoniter.ConfigDefault, input) for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { switch field { case "code": result.Code = iter.ReadUint64() default: iter.Skip() } } } } func Benchmark_json_skip(b *testing.B) { input := []byte(` { "_shards":{ "total" : 5, "successful" : 5, "failed" : 0 }, "hits":{ "total" : 1, "hits" : [ { "_index" : "twitter", "_type" : "tweet", "_id" : "1", "_source" : { "user" : "kimchy", "postDate" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" } } ] }, "code": 200 }`) for n := 0; n < b.N; n++ { result := TestResp{} json.Unmarshal(input, &result) } } golang-github-json-iterator-go-1.1.12/skip_tests/skip_test.go000066400000000000000000000016271420644465700242720ustar00rootroot00000000000000package skip_tests import ( "encoding/json" "errors" "github.com/json-iterator/go" "github.com/stretchr/testify/require" "io" "reflect" "testing" ) type testCase struct { ptr interface{} inputs []string } var testCases []testCase func Test_skip(t *testing.T) { for _, testCase := range testCases { valType := reflect.TypeOf(testCase.ptr).Elem() for _, input := range testCase.inputs { t.Run(input, func(t *testing.T) { should := require.New(t) ptrVal := reflect.New(valType) stdErr := json.Unmarshal([]byte(input), ptrVal.Interface()) iter := jsoniter.ParseString(jsoniter.ConfigDefault, input) iter.Skip() iter.ReadNil() // trigger looking forward err := iter.Error if err == io.EOF { err = nil } else { err = errors.New("remaining bytes") } if stdErr == nil { should.Nil(err) } else { should.NotNil(err) } }) } } } golang-github-json-iterator-go-1.1.12/skip_tests/string_test.go000066400000000000000000000005131420644465700246230ustar00rootroot00000000000000package skip_tests func init() { testCases = append(testCases, testCase{ ptr: (*string)(nil), inputs: []string{ `""`, // valid `"hello"`, // valid `"`, // invalid `"\"`, // invalid `"\x00"`, // invalid "\"\x00\"", // invalid "\"\t\"", // invalid `"\t"`, // valid }, }) } golang-github-json-iterator-go-1.1.12/skip_tests/struct_test.go000066400000000000000000000010631420644465700246420ustar00rootroot00000000000000package skip_tests func init() { testCases = append(testCases, testCase{ ptr: (*struct{})(nil), inputs: []string{ `{}`, // valid `{"hello":"world"}`, // valid `{hello:"world"}`, // invalid `{"hello:"world"}`, // invalid `{"hello","world"}`, // invalid `{"hello":{}`, // invalid `{"hello":{}}`, // valid `{"hello":{}}}`, // invalid `{"hello": { "hello": 1}}`, // valid `{abc}`, // invalid }, }) } golang-github-json-iterator-go-1.1.12/stream.go000066400000000000000000000122471420644465700213700ustar00rootroot00000000000000package jsoniter import ( "io" ) // stream is a io.Writer like object, with JSON specific write functions. // Error is not returned as return value, but stored as Error member on this stream instance. type Stream struct { cfg *frozenConfig out io.Writer buf []byte Error error indention int Attachment interface{} // open for customized encoder } // NewStream create new stream instance. // cfg can be jsoniter.ConfigDefault. // out can be nil if write to internal buffer. // bufSize is the initial size for the internal buffer in bytes. func NewStream(cfg API, out io.Writer, bufSize int) *Stream { return &Stream{ cfg: cfg.(*frozenConfig), out: out, buf: make([]byte, 0, bufSize), Error: nil, indention: 0, } } // Pool returns a pool can provide more stream with same configuration func (stream *Stream) Pool() StreamPool { return stream.cfg } // Reset reuse this stream instance by assign a new writer func (stream *Stream) Reset(out io.Writer) { stream.out = out stream.buf = stream.buf[:0] } // Available returns how many bytes are unused in the buffer. func (stream *Stream) Available() int { return cap(stream.buf) - len(stream.buf) } // Buffered returns the number of bytes that have been written into the current buffer. func (stream *Stream) Buffered() int { return len(stream.buf) } // Buffer if writer is nil, use this method to take the result func (stream *Stream) Buffer() []byte { return stream.buf } // SetBuffer allows to append to the internal buffer directly func (stream *Stream) SetBuffer(buf []byte) { stream.buf = buf } // Write writes the contents of p into the buffer. // It returns the number of bytes written. // If nn < len(p), it also returns an error explaining // why the write is short. func (stream *Stream) Write(p []byte) (nn int, err error) { stream.buf = append(stream.buf, p...) if stream.out != nil { nn, err = stream.out.Write(stream.buf) stream.buf = stream.buf[nn:] return } return len(p), nil } // WriteByte writes a single byte. func (stream *Stream) writeByte(c byte) { stream.buf = append(stream.buf, c) } func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) { stream.buf = append(stream.buf, c1, c2) } func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) { stream.buf = append(stream.buf, c1, c2, c3) } func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) { stream.buf = append(stream.buf, c1, c2, c3, c4) } func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) { stream.buf = append(stream.buf, c1, c2, c3, c4, c5) } // Flush writes any buffered data to the underlying io.Writer. func (stream *Stream) Flush() error { if stream.out == nil { return nil } if stream.Error != nil { return stream.Error } _, err := stream.out.Write(stream.buf) if err != nil { if stream.Error == nil { stream.Error = err } return err } stream.buf = stream.buf[:0] return nil } // WriteRaw write string out without quotes, just like []byte func (stream *Stream) WriteRaw(s string) { stream.buf = append(stream.buf, s...) } // WriteNil write null to stream func (stream *Stream) WriteNil() { stream.writeFourBytes('n', 'u', 'l', 'l') } // WriteTrue write true to stream func (stream *Stream) WriteTrue() { stream.writeFourBytes('t', 'r', 'u', 'e') } // WriteFalse write false to stream func (stream *Stream) WriteFalse() { stream.writeFiveBytes('f', 'a', 'l', 's', 'e') } // WriteBool write true or false into stream func (stream *Stream) WriteBool(val bool) { if val { stream.WriteTrue() } else { stream.WriteFalse() } } // WriteObjectStart write { with possible indention func (stream *Stream) WriteObjectStart() { stream.indention += stream.cfg.indentionStep stream.writeByte('{') stream.writeIndention(0) } // WriteObjectField write "field": with possible indention func (stream *Stream) WriteObjectField(field string) { stream.WriteString(field) if stream.indention > 0 { stream.writeTwoBytes(':', ' ') } else { stream.writeByte(':') } } // WriteObjectEnd write } with possible indention func (stream *Stream) WriteObjectEnd() { stream.writeIndention(stream.cfg.indentionStep) stream.indention -= stream.cfg.indentionStep stream.writeByte('}') } // WriteEmptyObject write {} func (stream *Stream) WriteEmptyObject() { stream.writeByte('{') stream.writeByte('}') } // WriteMore write , with possible indention func (stream *Stream) WriteMore() { stream.writeByte(',') stream.writeIndention(0) } // WriteArrayStart write [ with possible indention func (stream *Stream) WriteArrayStart() { stream.indention += stream.cfg.indentionStep stream.writeByte('[') stream.writeIndention(0) } // WriteEmptyArray write [] func (stream *Stream) WriteEmptyArray() { stream.writeTwoBytes('[', ']') } // WriteArrayEnd write ] with possible indention func (stream *Stream) WriteArrayEnd() { stream.writeIndention(stream.cfg.indentionStep) stream.indention -= stream.cfg.indentionStep stream.writeByte(']') } func (stream *Stream) writeIndention(delta int) { if stream.indention == 0 { return } stream.writeByte('\n') toWrite := stream.indention - delta for i := 0; i < toWrite; i++ { stream.buf = append(stream.buf, ' ') } } golang-github-json-iterator-go-1.1.12/stream_float.go000066400000000000000000000053001420644465700225450ustar00rootroot00000000000000package jsoniter import ( "fmt" "math" "strconv" ) var pow10 []uint64 func init() { pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000} } // WriteFloat32 write float32 to stream func (stream *Stream) WriteFloat32(val float32) { if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) { stream.Error = fmt.Errorf("unsupported value: %f", val) return } abs := math.Abs(float64(val)) fmt := byte('f') // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. if abs != 0 { if float32(abs) < 1e-6 || float32(abs) >= 1e21 { fmt = 'e' } } stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32) } // WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster func (stream *Stream) WriteFloat32Lossy(val float32) { if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) { stream.Error = fmt.Errorf("unsupported value: %f", val) return } if val < 0 { stream.writeByte('-') val = -val } if val > 0x4ffffff { stream.WriteFloat32(val) return } precision := 6 exp := uint64(1000000) // 6 lval := uint64(float64(val)*float64(exp) + 0.5) stream.WriteUint64(lval / exp) fval := lval % exp if fval == 0 { return } stream.writeByte('.') for p := precision - 1; p > 0 && fval < pow10[p]; p-- { stream.writeByte('0') } stream.WriteUint64(fval) for stream.buf[len(stream.buf)-1] == '0' { stream.buf = stream.buf[:len(stream.buf)-1] } } // WriteFloat64 write float64 to stream func (stream *Stream) WriteFloat64(val float64) { if math.IsInf(val, 0) || math.IsNaN(val) { stream.Error = fmt.Errorf("unsupported value: %f", val) return } abs := math.Abs(val) fmt := byte('f') // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. if abs != 0 { if abs < 1e-6 || abs >= 1e21 { fmt = 'e' } } stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64) } // WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster func (stream *Stream) WriteFloat64Lossy(val float64) { if math.IsInf(val, 0) || math.IsNaN(val) { stream.Error = fmt.Errorf("unsupported value: %f", val) return } if val < 0 { stream.writeByte('-') val = -val } if val > 0x4ffffff { stream.WriteFloat64(val) return } precision := 6 exp := uint64(1000000) // 6 lval := uint64(val*float64(exp) + 0.5) stream.WriteUint64(lval / exp) fval := lval % exp if fval == 0 { return } stream.writeByte('.') for p := precision - 1; p > 0 && fval < pow10[p]; p-- { stream.writeByte('0') } stream.WriteUint64(fval) for stream.buf[len(stream.buf)-1] == '0' { stream.buf = stream.buf[:len(stream.buf)-1] } } golang-github-json-iterator-go-1.1.12/stream_int.go000066400000000000000000000107441420644465700222420ustar00rootroot00000000000000package 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)) } golang-github-json-iterator-go-1.1.12/stream_str.go000066400000000000000000000174621420644465700222640ustar00rootroot00000000000000package jsoniter import ( "unicode/utf8" ) // htmlSafeSet holds the value true if the ASCII character with the given // array position can be safely represented inside a JSON string, embedded // inside of HTML