From d63a00f0bf185a7c739e81f5634f60ee0ad80b2c Mon Sep 17 00:00:00 2001 From: SuperFashi Date: Thu, 5 Jan 2017 21:23:08 +0800 Subject: [PATCH] Formated, doced. Also fixed few minor bugs. --- README.md | 4 +- any_test.go | 4 +- feature_adapter.go | 3 +- feature_any.go | 206 ++++++++++++++------------- feature_iter_object.go | 21 ++- feature_reflect.go | 162 ++++++++++----------- jsoniter.go | 271 +++++++++++++++++++----------------- jsoniter_any_test.go | 2 +- jsoniter_array_test.go | 4 +- jsoniter_base64_test.go | 5 +- jsoniter_customize_test.go | 12 +- jsoniter_demo_test.go | 10 +- jsoniter_find_end_test.go | 2 +- jsoniter_float_test.go | 4 +- jsoniter_int_test.go | 4 +- jsoniter_io_test.go | 4 +- jsoniter_large_file_test.go | 5 +- jsoniter_map_test.go | 6 +- jsoniter_nested_test.go | 10 +- jsoniter_null_test.go | 4 +- jsoniter_object_test.go | 6 +- jsoniter_reflect_test.go | 82 +++++------ jsoniter_skip_test.go | 5 +- jsoniter_string_test.go | 4 +- 24 files changed, 438 insertions(+), 402 deletions(-) diff --git a/README.md b/README.md index d286c5d9..d452d2ba 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![rcard](https://goreportcard.com/badge/github.com/json-iterator/go)](https://goreportcard.com/report/github.com/json-iterator/go) + jsoniter (json-iterator) is fast and flexible JSON parser available in [Java](https://github.com/json-iterator/java) and [Go](https://github.com/json-iterator/go) # Why jsoniter? @@ -37,7 +39,7 @@ import "github.com/json-iterator/go" iter := ParseString(`[0, [1, 2], [3, 4], 5]`) count := 0 for iter.ReadArray() { - iter.skip() + iter.Skip() count++ } fmt.Println(count) // 4 diff --git a/any_test.go b/any_test.go index 40b0e779..7fbcc4ca 100644 --- a/any_test.go +++ b/any_test.go @@ -1,8 +1,8 @@ package jsoniter import ( - "testing" "fmt" + "testing" ) func Test_get_from_map(t *testing.T) { @@ -36,7 +36,7 @@ func Test_is_null(t *testing.T) { any := Any{val: []interface{}{ 1, 2, 3, }} - if any.IsNull() != false { + if any.IsNil() != false { t.FailNow() } } diff --git a/feature_adapter.go b/feature_adapter.go index 4e96a159..2b0dfb45 100644 --- a/feature_adapter.go +++ b/feature_adapter.go @@ -2,8 +2,7 @@ package jsoniter import "io" -// adapt to json/encoding api - +// Unmarshal adapts to json/encoding APIs func Unmarshal(data []byte, v interface{}) error { iter := ParseBytes(data) iter.Read(v) diff --git a/feature_any.go b/feature_any.go index fcda7f68..b8ceb0dc 100644 --- a/feature_any.go +++ b/feature_any.go @@ -6,104 +6,109 @@ import ( "strconv" ) +// Any API is for maximum flexibility type Any struct { - val interface{} - Error error + val interface{} + Error error LastAccessed interface{} } +// MakeAny creates Any instance func MakeAny(val interface{}) *Any { return &Any{val, nil, nil} } +// Get extracts a json object from Any func (any *Any) Get(keys ...interface{}) interface{} { ret, err := getPath(any.val, keys...) any.LastAccessed = ret if err != nil { any.Error = err - return ""; + return "" } return ret } +// GetValueType gets type of a value func (any *Any) GetValueType(keys ...interface{}) ValueType { ret, err := getPath(any.val, keys...) any.LastAccessed = ret if err != nil { any.Error = err - return Invalid; + return Invalid } switch reflect.TypeOf(ret).Kind() { case reflect.Uint8: - return Number; + return Number case reflect.Int8: - return Number; + return Number case reflect.Uint16: - return Number; + return Number case reflect.Int16: - return Number; + return Number case reflect.Uint32: - return Number; + return Number case reflect.Int32: - return Number; + return Number case reflect.Uint64: - return Number; + return Number case reflect.Int64: - return Number; + return Number case reflect.Int: - return Number; + return Number case reflect.Uint: - return Number; + return Number case reflect.Float32: - return Number; + return Number case reflect.Float64: - return Number; + return Number case reflect.String: - return String; + return String case reflect.Bool: - return Bool; + return Bool case reflect.Array: - return Array; + return Array case reflect.Struct: - return Object; + return Object default: return Invalid } } +// ToString converts a json object to string func (any *Any) ToString(keys ...interface{}) string { ret, err := getPath(any.val, keys...) any.LastAccessed = ret if err != nil { any.Error = err - return ""; + return "" } switch ret := ret.(type) { case uint8: - return strconv.FormatInt(int64(ret), 10); + return strconv.FormatInt(int64(ret), 10) case int8: - return strconv.FormatInt(int64(ret), 10); + return strconv.FormatInt(int64(ret), 10) case uint16: - return strconv.FormatInt(int64(ret), 10); + return strconv.FormatInt(int64(ret), 10) case int16: - return strconv.FormatInt(int64(ret), 10); + return strconv.FormatInt(int64(ret), 10) case uint32: - return strconv.FormatInt(int64(ret), 10); + return strconv.FormatInt(int64(ret), 10) case int32: - return strconv.FormatInt(int64(ret), 10); + return strconv.FormatInt(int64(ret), 10) case uint64: - return strconv.FormatUint(uint64(ret), 10); + return strconv.FormatUint(uint64(ret), 10) case int64: - return strconv.FormatInt(int64(ret), 10); + return strconv.FormatInt(int64(ret), 10) case int: - return strconv.FormatInt(int64(ret), 10); + return strconv.FormatInt(int64(ret), 10) case uint: - return strconv.FormatInt(int64(ret), 10); + return strconv.FormatInt(int64(ret), 10) case float32: - return strconv.FormatFloat(float64(ret), 'E', -1, 32); + return strconv.FormatFloat(float64(ret), 'E', -1, 32) case float64: - return strconv.FormatFloat(ret, 'E', -1, 64); + return strconv.FormatFloat(ret, 'E', -1, 64) case string: return ret default: @@ -111,135 +116,149 @@ func (any *Any) ToString(keys ...interface{}) string { } } +// ToUint8 converts a json object to Uint8 func (any *Any) ToUint8(keys ...interface{}) uint8 { ret, err := getPathAsInt64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return uint8(ret) } +// ToInt8 converts a json object to Int8 func (any *Any) ToInt8(keys ...interface{}) int8 { ret, err := getPathAsInt64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return int8(ret) } +// ToUint16 converts a json object to Uint16 func (any *Any) ToUint16(keys ...interface{}) uint16 { ret, err := getPathAsInt64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return uint16(ret) } +// ToInt16 converts a json object to Int16 func (any *Any) ToInt16(keys ...interface{}) int16 { ret, err := getPathAsInt64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return int16(ret) } +// ToUint32 converts a json object to Uint32 func (any *Any) ToUint32(keys ...interface{}) uint32 { ret, err := getPathAsInt64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return uint32(ret) } +// ToInt32 converts a json object to Int32 func (any *Any) ToInt32(keys ...interface{}) int32 { ret, err := getPathAsInt64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return int32(ret) } +// ToUint64 converts a json object to Uint64 func (any *Any) ToUint64(keys ...interface{}) uint64 { ret, err := getPathAsUint64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return uint64(ret) } +// ToInt64 converts a json object to Int64 func (any *Any) ToInt64(keys ...interface{}) int64 { ret, err := getPathAsInt64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return int64(ret) } +// ToInt converts a json object to Int func (any *Any) ToInt(keys ...interface{}) int { ret, err := getPathAsInt64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return int(ret) } +// ToUint converts a json object to Uint func (any *Any) ToUint(keys ...interface{}) uint { ret, err := getPathAsInt64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return uint(ret) } +// ToFloat32 converts a json object to Float32 func (any *Any) ToFloat32(keys ...interface{}) float32 { ret, err := getPathAsFloat64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return float32(ret) } +// ToFloat64 converts a json object to Float64 func (any *Any) ToFloat64(keys ...interface{}) float64 { ret, err := getPathAsFloat64(any, keys...) if err != nil { any.Error = err - return 0; + return 0 } return ret } +// ToBool converts a json object to Bool func (any *Any) ToBool(keys ...interface{}) bool { ret, err := getPath(any.val, keys...) any.LastAccessed = ret if err != nil { any.Error = err - return false; + return false } typedRet, ok := ret.(bool) if !ok { any.Error = fmt.Errorf("%v is not bool", ret) - return false; + return false } return typedRet } -func (any *Any) IsNull(keys ...interface{}) bool { +// IsNil judges whether a json object is nil +func (any *Any) IsNil(keys ...interface{}) bool { ret, err := getPath(any.val, keys...) any.LastAccessed = ret if err != nil { any.Error = err - return false; + return false } return reflect.ValueOf(ret).IsNil() } @@ -253,35 +272,35 @@ func getPathAsInt64(any *Any, keys ...interface{}) (int64, error) { } switch ret := ret.(type) { case uint8: - return int64(ret), nil; + return int64(ret), nil case int8: - return int64(ret), nil; + return int64(ret), nil case uint16: - return int64(ret), nil; + return int64(ret), nil case int16: - return int64(ret), nil; + return int64(ret), nil case uint32: - return int64(ret), nil; + return int64(ret), nil case int32: - return int64(ret), nil; + return int64(ret), nil case uint64: - return int64(ret), nil; + return int64(ret), nil case int64: - return int64(ret), nil; + return int64(ret), nil case int: - return int64(ret), nil; + return int64(ret), nil case uint: - return int64(ret), nil; + return int64(ret), nil case float32: - return int64(ret), nil; + return int64(ret), nil case float64: - return int64(ret), nil; + return int64(ret), nil case string: intVal, err := strconv.ParseInt(ret, 10, 64) if err != nil { return 0, err } - return intVal, nil; + return intVal, nil default: return 0, fmt.Errorf("%v is not number", ret) } @@ -296,35 +315,35 @@ func getPathAsUint64(any *Any, keys ...interface{}) (uint64, error) { } switch ret := ret.(type) { case uint8: - return uint64(ret), nil; + return uint64(ret), nil case int8: - return uint64(ret), nil; + return uint64(ret), nil case uint16: - return uint64(ret), nil; + return uint64(ret), nil case int16: - return uint64(ret), nil; + return uint64(ret), nil case uint32: - return uint64(ret), nil; + return uint64(ret), nil case int32: - return uint64(ret), nil; + return uint64(ret), nil case uint64: - return uint64(ret), nil; + return uint64(ret), nil case int64: - return uint64(ret), nil; + return uint64(ret), nil case int: - return uint64(ret), nil; + return uint64(ret), nil case uint: - return uint64(ret), nil; + return uint64(ret), nil case float32: - return uint64(ret), nil; + return uint64(ret), nil case float64: - return uint64(ret), nil; + return uint64(ret), nil case string: intVal, err := strconv.ParseUint(ret, 10, 64) if err != nil { return 0, err } - return intVal, nil; + return intVal, nil default: return 0, fmt.Errorf("%v is not number", ret) } @@ -339,43 +358,43 @@ func getPathAsFloat64(any *Any, keys ...interface{}) (float64, error) { } switch ret := ret.(type) { case uint8: - return float64(ret), nil; + return float64(ret), nil case int8: - return float64(ret), nil; + return float64(ret), nil case uint16: - return float64(ret), nil; + return float64(ret), nil case int16: - return float64(ret), nil; + return float64(ret), nil case uint32: - return float64(ret), nil; + return float64(ret), nil case int32: - return float64(ret), nil; + return float64(ret), nil case uint64: - return float64(ret), nil; + return float64(ret), nil case int64: - return float64(ret), nil; + return float64(ret), nil case int: - return float64(ret), nil; + return float64(ret), nil case uint: - return float64(ret), nil; + return float64(ret), nil case float32: - return float64(ret), nil; + return float64(ret), nil case float64: - return float64(ret), nil; + return float64(ret), nil case string: floatVal, err := strconv.ParseFloat(ret, 64) if err != nil { return 0, err } - return floatVal, nil; + return floatVal, nil default: return 0, fmt.Errorf("%v is not number", ret) } } func getPath(val interface{}, keys ...interface{}) (interface{}, error) { - if (len(keys) == 0) { - return val, nil; + if len(keys) == 0 { + return val, nil } switch key := keys[0].(type) { case string: @@ -383,7 +402,7 @@ func getPath(val interface{}, keys ...interface{}) (interface{}, error) { if err != nil { return nil, err } - nextKeys := make([]interface{}, len(keys) - 1) + nextKeys := make([]interface{}, len(keys)-1) copy(nextKeys, keys[1:]) return getPath(nextVal, nextKeys...) case int: @@ -391,13 +410,12 @@ func getPath(val interface{}, keys ...interface{}) (interface{}, error) { if err != nil { return nil, err } - nextKeys := make([]interface{}, len(keys) - 1) + nextKeys := make([]interface{}, len(keys)-1) copy(nextKeys, keys[1:]) return getPath(nextVal, nextKeys...) default: - return nil, fmt.Errorf("%v is not string or int", keys[0]); + return nil, fmt.Errorf("%v is not string or int", keys[0]) } - return getPath(val, keys); } func getFromMap(val interface{}, key string) (interface{}, error) { diff --git a/feature_iter_object.go b/feature_iter_object.go index c9d6b039..242d4146 100644 --- a/feature_iter_object.go +++ b/feature_iter_object.go @@ -2,20 +2,20 @@ package jsoniter import "unsafe" +// ReadObject is a implemented iterator for json func (iter *Iterator) ReadObject() (ret string) { c := iter.nextToken() if iter.Error != nil { return } switch c { - case 'n': { + case 'n': iter.skipUntilBreak() if iter.Error != nil { return } return "" // null - } - case '{': { + case '{': c = iter.nextToken() if iter.Error != nil { return @@ -27,16 +27,15 @@ func (iter *Iterator) ReadObject() (ret string) { iter.unreadByte() return iter.readObjectField() default: - iter.ReportError("ReadObject", `expect " after {`) + iter.reportError("ReadObject", `expect " after {`) return } - } case ',': return iter.readObjectField() case '}': return "" // end of object default: - iter.ReportError("ReadObject", `expect { or , or } or n`) + iter.reportError("ReadObject", `expect { or , or } or n`) return } } @@ -51,7 +50,7 @@ func (iter *Iterator) readObjectStart() bool { iter.unreadByte() return true } - iter.ReportError("readObjectStart", "expect { ") + iter.reportError("readObjectStart", "expect { ") return false } @@ -59,20 +58,20 @@ func (iter *Iterator) readObjectField() (ret string) { str := iter.readStringAsBytes() if iter.skipWhitespacesWithoutLoadMore() { if ret == "" { - ret = string(str); + ret = string(str) } if !iter.loadMore() { return } } if iter.buf[iter.head] != ':' { - iter.ReportError("ReadObject", "expect : after object field") + iter.reportError("ReadObject", "expect : after object field") return } iter.head++ if iter.skipWhitespacesWithoutLoadMore() { if ret == "" { - ret = string(str); + ret = string(str) } if !iter.loadMore() { return @@ -82,4 +81,4 @@ func (iter *Iterator) readObjectField() (ret string) { return *(*string)(unsafe.Pointer(&str)) } return ret -} \ No newline at end of file +} diff --git a/feature_reflect.go b/feature_reflect.go index 2eaae8b2..bbfb1557 100644 --- a/feature_reflect.go +++ b/feature_reflect.go @@ -1,14 +1,14 @@ package jsoniter import ( - "reflect" "errors" "fmt" - "unsafe" - "sync/atomic" - "strings" "io" + "reflect" "strconv" + "strings" + "sync/atomic" + "unsafe" ) /* @@ -18,8 +18,9 @@ Reflection on value is avoided as we can, as the reflect.Value itself will alloc 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 - */ +*/ +// Decoder works like a father class for sub-type decoders type Decoder interface { decode(ptr unsafe.Pointer, iter *Iterator) } @@ -129,7 +130,6 @@ func (decoder *interfaceDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { *((*interface{})(ptr)) = iter.ReadAny().Get() } - type anyDecoder struct { } @@ -144,7 +144,7 @@ type stringNumberDecoder struct { func (decoder *stringNumberDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { c := iter.nextToken() if c != '"' { - iter.ReportError("stringNumberDecoder", `expect "`) + iter.reportError("stringNumberDecoder", `expect "`) return } decoder.elemDecoder.decode(ptr, iter) @@ -153,7 +153,7 @@ func (decoder *stringNumberDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { } c = iter.readByte() if c != '"' { - iter.ReportError("stringNumberDecoder", `expect "`) + iter.reportError("stringNumberDecoder", `expect "`) return } } @@ -164,7 +164,7 @@ type optionalDecoder struct { } func (decoder *optionalDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.ReadNull() { + if iter.ReadNil() { *((*unsafe.Pointer)(ptr)) = nil } else { if *((*unsafe.Pointer)(ptr)) == nil { @@ -180,7 +180,7 @@ func (decoder *optionalDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { } type generalStructDecoder struct { - type_ reflect.Type + typ reflect.Type fields map[string]*structFieldDecoder } @@ -194,23 +194,23 @@ func (decoder *generalStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error()) + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) } } type skipDecoder struct { - type_ reflect.Type + typ reflect.Type } func (decoder *skipDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { iter.Skip() if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error()) + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) } } type oneFieldStructDecoder struct { - type_ reflect.Type + typ reflect.Type fieldName string fieldDecoder *structFieldDecoder } @@ -224,12 +224,12 @@ func (decoder *oneFieldStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error()) + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) } } type twoFieldsStructDecoder struct { - type_ reflect.Type + typ reflect.Type fieldName1 string fieldDecoder1 *structFieldDecoder fieldName2 string @@ -248,12 +248,12 @@ func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error()) + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) } } type threeFieldsStructDecoder struct { - type_ reflect.Type + typ reflect.Type fieldName1 string fieldDecoder1 *structFieldDecoder fieldName2 string @@ -276,12 +276,12 @@ func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterat } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error()) + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) } } type fourFieldsStructDecoder struct { - type_ reflect.Type + typ reflect.Type fieldName1 string fieldDecoder1 *structFieldDecoder fieldName2 string @@ -325,7 +325,7 @@ func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterato } } if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error()) + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) } } @@ -343,9 +343,9 @@ func (decoder *structFieldDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { } type mapDecoder struct { - mapType reflect.Type - elemType reflect.Type - elemDecoder Decoder + mapType reflect.Type + elemType reflect.Type + elemDecoder Decoder mapInterface emptyInterface } @@ -391,30 +391,30 @@ func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { return } offset := uintptr(0) - decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter) + decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter) if !iter.ReadArray() { slice.Len = 1 return } offset += decoder.elemType.Size() - decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter) + decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter) if !iter.ReadArray() { slice.Len = 2 return } offset += decoder.elemType.Size() - decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter) + decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter) if !iter.ReadArray() { slice.Len = 3 return } offset += decoder.elemType.Size() - decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter) + decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter) slice.Len = 4 for iter.ReadArray() { growOne(slice, decoder.sliceType, decoder.elemType) offset += decoder.elemType.Size() - decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter) + decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter) } } @@ -494,29 +494,33 @@ func init() { } type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) -type ExtensionFunc func(type_ reflect.Type, field *reflect.StructField) ([]string, DecoderFunc) +type ExtensionFunc func(typ reflect.Type, field *reflect.StructField) ([]string, DecoderFunc) type funcDecoder struct { - func_ DecoderFunc + fun DecoderFunc } func (decoder *funcDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.func_(ptr, iter) + decoder.fun(ptr, iter) } -func RegisterTypeDecoder(type_ string, func_ DecoderFunc) { - typeDecoders[type_] = &funcDecoder{func_} +// RegisterTypeDecoder can register a type for json object +func RegisterTypeDecoder(typ string, fun DecoderFunc) { + typeDecoders[typ] = &funcDecoder{fun} } -func RegisterFieldDecoder(type_ string, field string, func_ DecoderFunc) { - fieldDecoders[fmt.Sprintf("%s/%s", type_, field)] = &funcDecoder{func_} +// RegisterFieldDecoder can register a type for json field +func RegisterFieldDecoder(typ string, field string, fun DecoderFunc) { + fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = &funcDecoder{fun} } +// RegisterExtension can register a custom extension func RegisterExtension(extension ExtensionFunc) { extensions = append(extensions, extension) } -func ClearDecoders() { +// CleanDecoders cleans decoders registered +func CleanDecoders() { typeDecoders = map[string]Decoder{} fieldDecoders = map[string]Decoder{} } @@ -527,6 +531,7 @@ type emptyInterface struct { word unsafe.Pointer } +// ReadAny converts a json object in a Iterator instance to Any func (iter *Iterator) ReadAny() (ret *Any) { valueType := iter.WhatIsNext() switch valueType { @@ -540,7 +545,7 @@ func (iter *Iterator) ReadAny() (ret *Any) { return MakeAny(iter.ReadBool()) case Array: val := []interface{}{} - for (iter.ReadArray()) { + for iter.ReadArray() { element := iter.ReadAny() if iter.Error != nil { return @@ -559,20 +564,18 @@ func (iter *Iterator) ReadAny() (ret *Any) { } return MakeAny(val) default: - iter.ReportError("ReadAny", fmt.Sprintf("unexpected value type: %v", valueType)) + iter.reportError("ReadAny", fmt.Sprintf("unexpected value type: %v", valueType)) return MakeAny(nil) } } - - func (iter *Iterator) readNumber() (ret *Any) { strBuf := [8]byte{} str := strBuf[0:0] hasMore := true foundFloat := false foundNegative := false - for(hasMore) { + for hasMore { for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] switch c { @@ -630,12 +633,13 @@ func (iter *Iterator) readNumber() (ret *Any) { return MakeAny(val) } +// Read converts an Iterator instance into go interface, same as json.Unmarshal func (iter *Iterator) Read(obj interface{}) { - type_ := reflect.TypeOf(obj) - cacheKey := type_.Elem() + typ := reflect.TypeOf(obj) + cacheKey := typ.Elem() cachedDecoder := getDecoderFromCache(cacheKey) if cachedDecoder == nil { - decoder, err := decoderOfType(type_) + decoder, err := decoderOfType(typ) if err != nil { iter.Error = err return @@ -656,17 +660,17 @@ func (p prefix) addTo(decoder Decoder, err error) (Decoder, error) { return decoder, err } -func decoderOfType(type_ reflect.Type) (Decoder, error) { - switch type_.Kind() { +func decoderOfType(typ reflect.Type) (Decoder, error) { + switch typ.Kind() { case reflect.Ptr: - return prefix("ptr").addTo(decoderOfPtr(type_.Elem())) + return prefix("ptr").addTo(decoderOfPtr(typ.Elem())) default: return nil, errors.New("expect ptr") } } -func decoderOfPtr(type_ reflect.Type) (Decoder, error) { - typeName := type_.String() +func decoderOfPtr(typ reflect.Type) (Decoder, error) { + typeName := typ.String() if typeName == "jsoniter.Any" { return &anyDecoder{}, nil } @@ -674,7 +678,7 @@ func decoderOfPtr(type_ reflect.Type) (Decoder, error) { if typeDecoder != nil { return typeDecoder, nil } - switch type_.Kind() { + switch typ.Kind() { case reflect.String: return &stringDecoder{}, nil case reflect.Int: @@ -706,39 +710,39 @@ func decoderOfPtr(type_ reflect.Type) (Decoder, error) { case reflect.Interface: return &interfaceDecoder{}, nil case reflect.Struct: - return decoderOfStruct(type_) + return decoderOfStruct(typ) case reflect.Slice: - return prefix("[slice]").addTo(decoderOfSlice(type_)) + return prefix("[slice]").addTo(decoderOfSlice(typ)) case reflect.Map: - return prefix("[map]").addTo(decoderOfMap(type_)) + return prefix("[map]").addTo(decoderOfMap(typ)) case reflect.Ptr: - return prefix("[optional]").addTo(decoderOfOptional(type_.Elem())) + return prefix("[optional]").addTo(decoderOfOptional(typ.Elem())) default: - return nil, fmt.Errorf("unsupported type: %v", type_) + return nil, fmt.Errorf("unsupported type: %v", typ) } } -func decoderOfOptional(type_ reflect.Type) (Decoder, error) { - decoder, err := decoderOfPtr(type_) +func decoderOfOptional(typ reflect.Type) (Decoder, error) { + decoder, err := decoderOfPtr(typ) if err != nil { return nil, err } - return &optionalDecoder{type_, decoder}, nil + return &optionalDecoder{typ, decoder}, nil } -func decoderOfStruct(type_ reflect.Type) (Decoder, error) { +func decoderOfStruct(typ reflect.Type) (Decoder, error) { fields := map[string]*structFieldDecoder{} - for i := 0; i < type_.NumField(); i++ { - field := type_.Field(i) - fieldDecoderKey := fmt.Sprintf("%s/%s", type_.String(), field.Name) + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + fieldDecoderKey := fmt.Sprintf("%s/%s", typ.String(), field.Name) var fieldNames []string for _, extension := range extensions { - alternativeFieldNames, func_ := extension(type_, &field) + alternativeFieldNames, fun := extension(typ, &field) if alternativeFieldNames != nil { fieldNames = alternativeFieldNames } - if func_ != nil { - fieldDecoders[fieldDecoderKey] = &funcDecoder{func_} + if fun != nil { + fieldDecoders[fieldDecoderKey] = &funcDecoder{fun} } } decoder := fieldDecoders[fieldDecoderKey] @@ -771,10 +775,10 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) { } switch len(fields) { case 0: - return &skipDecoder{type_}, nil + return &skipDecoder{typ}, nil case 1: for fieldName, fieldDecoder := range fields { - return &oneFieldStructDecoder{type_, fieldName, fieldDecoder}, nil + return &oneFieldStructDecoder{typ, fieldName, fieldDecoder}, nil } case 2: var fieldName1 string @@ -790,7 +794,7 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) { fieldDecoder2 = fieldDecoder } } - return &twoFieldsStructDecoder{type_, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2}, nil + return &twoFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2}, nil case 3: var fieldName1 string var fieldName2 string @@ -810,7 +814,7 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) { fieldDecoder3 = fieldDecoder } } - return &threeFieldsStructDecoder{type_, + return &threeFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil case 4: var fieldName1 string @@ -836,26 +840,26 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) { fieldDecoder4 = fieldDecoder } } - return &fourFieldsStructDecoder{type_, + return &fourFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, fieldName4, fieldDecoder4}, nil } - return &generalStructDecoder{type_, fields}, nil + return &generalStructDecoder{typ, fields}, nil } -func decoderOfSlice(type_ reflect.Type) (Decoder, error) { - decoder, err := decoderOfPtr(type_.Elem()) +func decoderOfSlice(typ reflect.Type) (Decoder, error) { + decoder, err := decoderOfPtr(typ.Elem()) if err != nil { return nil, err } - return &sliceDecoder{type_, type_.Elem(), decoder}, nil + return &sliceDecoder{typ, typ.Elem(), decoder}, nil } -func decoderOfMap(type_ reflect.Type) (Decoder, error) { - decoder, err := decoderOfPtr(type_.Elem()) +func decoderOfMap(typ reflect.Type) (Decoder, error) { + decoder, err := decoderOfPtr(typ.Elem()) if err != nil { return nil, err } - mapInterface := reflect.New(type_).Interface() - return &mapDecoder{type_, type_.Elem(), decoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil + mapInterface := reflect.New(typ).Interface() + return &mapDecoder{typ, typ.Elem(), decoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil } diff --git a/jsoniter.go b/jsoniter.go index 64a3ae26..d1c316dc 100644 --- a/jsoniter.go +++ b/jsoniter.go @@ -1,12 +1,12 @@ package jsoniter import ( - "io" + "encoding/base64" "fmt" - "unicode/utf16" + "io" "strconv" + "unicode/utf16" "unsafe" - "encoding/base64" ) type ValueType int @@ -30,37 +30,38 @@ func init() { digits[i] = 255 } for i := '0'; i <= '9'; i++ { - digits[i] = byte(i - '0'); + digits[i] = byte(i - '0') } for i := 'a'; i <= 'f'; i++ { - digits[i] = byte((i - 'a') + 10); + digits[i] = byte((i - 'a') + 10) } for i := 'A'; i <= 'F'; i++ { - digits[i] = byte((i - 'A') + 10); + digits[i] = byte((i - 'A') + 10) } valueTypes = make([]ValueType, 256) for i := 0; i < len(valueTypes); i++ { valueTypes[i] = Invalid } - valueTypes['"'] = String; - valueTypes['-'] = Number; - valueTypes['0'] = Number; - valueTypes['1'] = Number; - valueTypes['2'] = Number; - valueTypes['3'] = Number; - valueTypes['4'] = Number; - valueTypes['5'] = Number; - valueTypes['6'] = Number; - valueTypes['7'] = Number; - valueTypes['8'] = Number; - valueTypes['9'] = Number; - valueTypes['t'] = Bool; - valueTypes['f'] = Bool; - valueTypes['n'] = Null; - valueTypes['['] = Array; - valueTypes['{'] = Object; -} - + valueTypes['"'] = String + valueTypes['-'] = Number + valueTypes['0'] = Number + valueTypes['1'] = Number + valueTypes['2'] = Number + valueTypes['3'] = Number + valueTypes['4'] = Number + valueTypes['5'] = Number + valueTypes['6'] = Number + valueTypes['7'] = Number + valueTypes['8'] = Number + valueTypes['9'] = Number + valueTypes['t'] = Bool + valueTypes['f'] = Bool + valueTypes['n'] = Null + valueTypes['['] = Array + valueTypes['{'] = Object +} + +// Iterator is a fast and flexible JSON parser type Iterator struct { reader io.Reader buf []byte @@ -69,37 +70,42 @@ type Iterator struct { Error error } +// Create creates an empty Iterator instance func Create() *Iterator { return &Iterator{ reader: nil, - buf: nil, - head: 0, - tail: 0, + buf: nil, + head: 0, + tail: 0, } } +// Parse parses a json buffer in io.Reader into an Iterator instance func Parse(reader io.Reader, bufSize int) *Iterator { return &Iterator{ reader: reader, - buf: make([]byte, bufSize), - head: 0, - tail: 0, + buf: make([]byte, bufSize), + head: 0, + tail: 0, } } +// ParseBytes parses a json byte slice into an Iterator instance func ParseBytes(input []byte) *Iterator { return &Iterator{ reader: nil, - buf: input, - head: 0, - tail: len(input), + buf: input, + head: 0, + tail: len(input), } } +// ParseString parses a json string into an Iterator instance func ParseString(input string) *Iterator { return ParseBytes([]byte(input)) } +// Reset can reset an Iterator instance for another json buffer in io.Reader func (iter *Iterator) Reset(reader io.Reader) *Iterator { iter.reader = reader iter.head = 0 @@ -107,6 +113,7 @@ func (iter *Iterator) Reset(reader io.Reader) *Iterator { return iter } +// ResetBytes can reset an Iterator instance for another json byte slice func (iter *Iterator) ResetBytes(input []byte) *Iterator { iter.reader = nil iter.Error = nil @@ -116,10 +123,11 @@ func (iter *Iterator) ResetBytes(input []byte) *Iterator { return iter } +// WhatIsNext gets ValueType of relatively next json object func (iter *Iterator) WhatIsNext() ValueType { - valueType := valueTypes[iter.nextToken()]; - iter.unreadByte(); - return valueType; + valueType := valueTypes[iter.nextToken()] + iter.unreadByte() + return valueType } func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool { @@ -144,7 +152,7 @@ func (iter *Iterator) nextToken() byte { case ' ', '\n', '\t', '\r': continue } - iter.head = i+1 + iter.head = i + 1 return c } if !iter.loadMore() { @@ -153,7 +161,7 @@ func (iter *Iterator) nextToken() byte { } } -func (iter *Iterator) ReportError(operation string, msg string) { +func (iter *Iterator) reportError(operation string, msg string) { if iter.Error != nil { return } @@ -162,16 +170,17 @@ func (iter *Iterator) ReportError(operation string, msg string) { peekStart = 0 } iter.Error = fmt.Errorf("%s: %s, parsing %v ...%s... at %s", operation, msg, iter.head, - string(iter.buf[peekStart: iter.head]), string(iter.buf[0:iter.tail])) + string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) } +// CurrentBuffer gets current buffer as string func (iter *Iterator) CurrentBuffer() string { peekStart := iter.head - 10 if peekStart < 0 { peekStart = 0 } return fmt.Sprintf("parsing %v ...|%s|... at %s", iter.head, - string(iter.buf[peekStart: iter.head]), string(iter.buf[0:iter.tail])) + string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) } func (iter *Iterator) readByte() (ret byte) { @@ -180,9 +189,8 @@ func (iter *Iterator) readByte() (ret byte) { ret = iter.buf[iter.head] iter.head++ return ret - } else { - return 0 } + return 0 } ret = iter.buf[iter.head] iter.head++ @@ -200,9 +208,6 @@ func (iter *Iterator) loadMore() bool { if err != nil { iter.Error = err return false - } else { - // n == 0, err == nil is not EOF - continue } } else { iter.head = 0 @@ -214,58 +219,63 @@ func (iter *Iterator) loadMore() bool { func (iter *Iterator) unreadByte() { if iter.head == 0 { - iter.ReportError("unreadByte", "unread too many bytes") + iter.reportError("unreadByte", "unread too many bytes") return } - iter.head -= 1 + iter.head-- return } -const maxUint64 = (1 << 64 - 1) -const cutoffUint64 = maxUint64 / 10 + 1 -const maxUint32 = (1 << 32 - 1) -const cutoffUint32 = maxUint32 / 10 + 1 +const maxUint64 = (1<<64 - 1) +const cutoffUint64 = maxUint64/10 + 1 +const maxUint32 = (1<<32 - 1) +const cutoffUint32 = maxUint32/10 + 1 +// ReadUint reads a json object as Uint func (iter *Iterator) ReadUint() (ret uint) { val := iter.ReadUint64() converted := uint(val) if uint64(converted) != val { - iter.ReportError("ReadUint", "int overflow") + iter.reportError("ReadUint", "int overflow") return } return converted } +// ReadUint8 reads a json object as Uint8 func (iter *Iterator) ReadUint8() (ret uint8) { val := iter.ReadUint64() converted := uint8(val) if uint64(converted) != val { - iter.ReportError("ReadUint8", "int overflow") + iter.reportError("ReadUint8", "int overflow") return } return converted } +// ReadUint16 reads a json object as Uint16 func (iter *Iterator) ReadUint16() (ret uint16) { val := iter.ReadUint64() converted := uint16(val) if uint64(converted) != val { - iter.ReportError("ReadUint16", "int overflow") + iter.reportError("ReadUint16", "int overflow") return } return converted } +// ReadUint32 reads a json object as Uint32 func (iter *Iterator) ReadUint32() (ret uint32) { val := iter.ReadUint64() converted := uint32(val) if uint64(converted) != val { - iter.ReportError("ReadUint32", "int overflow") + iter.reportError("ReadUint32", "int overflow") return } return converted } +// ReadUint64 reads a json object as Uint64 func (iter *Iterator) ReadUint64() (ret uint64) { c := iter.nextToken() v := digits[c] @@ -273,15 +283,15 @@ func (iter *Iterator) ReadUint64() (ret uint64) { return 0 // single zero } if v == 255 { - iter.ReportError("ReadUint64", "unexpected character") + iter.reportError("ReadUint64", "unexpected character") return } for { if ret >= cutoffUint64 { - iter.ReportError("ReadUint64", "overflow") + iter.reportError("ReadUint64", "overflow") return } - ret = ret * 10 + uint64(v) + ret = ret*10 + uint64(v) c = iter.readByte() v = digits[c] if v == 255 { @@ -292,46 +302,51 @@ func (iter *Iterator) ReadUint64() (ret uint64) { return ret } +// ReadInt reads a json object as Int func (iter *Iterator) ReadInt() (ret int) { val := iter.ReadInt64() converted := int(val) if int64(converted) != val { - iter.ReportError("ReadInt", "int overflow") + iter.reportError("ReadInt", "int overflow") return } return converted } +// ReadInt8 reads a json object as Int8 func (iter *Iterator) ReadInt8() (ret int8) { val := iter.ReadInt64() converted := int8(val) if int64(converted) != val { - iter.ReportError("ReadInt8", "int overflow") + iter.reportError("ReadInt8", "int overflow") return } return converted } +// ReadInt16 reads a json object as Int16 func (iter *Iterator) ReadInt16() (ret int16) { val := iter.ReadInt64() converted := int16(val) if int64(converted) != val { - iter.ReportError("ReadInt16", "int overflow") + iter.reportError("ReadInt16", "int overflow") return } return converted } +// ReadInt32 reads a json object as Int32 func (iter *Iterator) ReadInt32() (ret int32) { val := iter.ReadInt64() converted := int32(val) if int64(converted) != val { - iter.ReportError("ReadInt32", "int overflow") + iter.reportError("ReadInt32", "int overflow") return } return converted } +// ReadInt64 reads a json object as Int64 func (iter *Iterator) ReadInt64() (ret int64) { c := iter.nextToken() if iter.Error != nil { @@ -342,25 +357,24 @@ func (iter *Iterator) ReadInt64() (ret int64) { if c == '-' { n := iter.ReadUint64() return -int64(n) - } else { - iter.unreadByte() - n := iter.ReadUint64() - return int64(n) } + iter.unreadByte() + n := iter.ReadUint64() + return int64(n) } +// ReadString reads a json object as String func (iter *Iterator) ReadString() (ret string) { return string(iter.readStringAsBytes()) } - func (iter *Iterator) readStringAsBytes() (ret []byte) { c := iter.nextToken() if c == '"' { end := iter.findStringEndWithoutEscape() if end != -1 { // fast path: reuse the underlying buffer - ret = iter.buf[iter.head:end-1] + ret = iter.buf[iter.head : end-1] iter.head = end return ret } @@ -370,7 +384,7 @@ func (iter *Iterator) readStringAsBytes() (ret []byte) { iter.skipUntilBreak() return } - iter.ReportError("ReadString", `expects " or n`) + iter.reportError("ReadString", `expects " or n`) return } @@ -399,7 +413,7 @@ func (iter *Iterator) readStringAsBytesSlowPath() (ret []byte) { return } if c != '\\' { - iter.ReportError("ReadString", + iter.reportError("ReadString", `expects \u after utf16 surrogate, but \ not found`) return } @@ -408,7 +422,7 @@ func (iter *Iterator) readStringAsBytesSlowPath() (ret []byte) { return } if c != 'u' { - iter.ReportError("ReadString", + iter.reportError("ReadString", `expects \u after utf16 surrogate, but \u not found`) return } @@ -438,7 +452,7 @@ func (iter *Iterator) readStringAsBytesSlowPath() (ret []byte) { case 't': str = append(str, '\t') default: - iter.ReportError("ReadString", + iter.reportError("ReadString", `invalid escape char after \`) return } @@ -455,20 +469,20 @@ func (iter *Iterator) readU4() (ret rune) { if iter.Error != nil { return } - if (c >= '0' && c <= '9') { + if c >= '0' && c <= '9' { if ret >= cutoffUint32 { - iter.ReportError("readU4", "overflow") + iter.reportError("readU4", "overflow") return } - ret = ret * 16 + rune(c - '0') - } else if ((c >= 'a' && c <= 'f') ) { + ret = ret*16 + rune(c-'0') + } else if c >= 'a' && c <= 'f' { if ret >= cutoffUint32 { - iter.ReportError("readU4", "overflow") + iter.reportError("readU4", "overflow") return } - ret = ret * 16 + rune(c - 'a' + 10) + ret = ret*16 + rune(c-'a'+10) } else { - iter.ReportError("readU4", "expects 0~9 or a~f") + iter.reportError("readU4", "expects 0~9 or a~f") return } } @@ -488,14 +502,14 @@ const ( mask3 = 0x0F // 0000 1111 mask4 = 0x07 // 0000 0111 - rune1Max = 1 << 7 - 1 - rune2Max = 1 << 11 - 1 - rune3Max = 1 << 16 - 1 + rune1Max = 1<<7 - 1 + rune2Max = 1<<11 - 1 + rune3Max = 1<<16 - 1 surrogateMin = 0xD800 surrogateMax = 0xDFFF - MaxRune = '\U0010FFFF' // Maximum valid Unicode code point. + MaxRune = '\U0010FFFF' // Maximum valid Unicode code point. RuneError = '\uFFFD' // the "error" Rune or "Unicode replacement character" ) @@ -506,62 +520,62 @@ func appendRune(p []byte, r rune) []byte { p = append(p, byte(r)) return p case i <= rune2Max: - p = append(p, t2 | byte(r >> 6)) - p = append(p, tx | byte(r) & maskx) + 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) + 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) + 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 } } +// ReadArray reads a json object as Array func (iter *Iterator) ReadArray() (ret bool) { c := iter.nextToken() if iter.Error != nil { return } switch c { - case 'n': { + case 'n': iter.skipUntilBreak() return false // null - } - case '[': { + case '[': c = iter.nextToken() if iter.Error != nil { return } if c == ']' { return false - } else { - iter.unreadByte() - return true } - } - case ']': return false + iter.unreadByte() + return true + case ']': + return false case ',': return true default: - iter.ReportError("ReadArray", "expect [ or , or ] or n, but found: " + string([]byte{c})) + iter.reportError("ReadArray", "expect [ or , or ] or n, but found: "+string([]byte{c})) return } } +// ReadFloat32 reads a json object as Float32 func (iter *Iterator) ReadFloat32() (ret float32) { strBuf := [8]byte{} str := strBuf[0:0] hasMore := true - for(hasMore) { + for hasMore { for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] switch c { @@ -590,11 +604,12 @@ func (iter *Iterator) ReadFloat32() (ret float32) { return float32(val) } +// ReadFloat64 reads a json object as Float64 func (iter *Iterator) ReadFloat64() (ret float64) { strBuf := [8]byte{} str := strBuf[0:0] hasMore := true - for(hasMore) { + for hasMore { for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] switch c { @@ -623,6 +638,7 @@ func (iter *Iterator) ReadFloat64() (ret float64) { return val } +// ReadBool reads a json object as Bool func (iter *Iterator) ReadBool() (ret bool) { c := iter.nextToken() if iter.Error != nil { @@ -636,11 +652,12 @@ func (iter *Iterator) ReadBool() (ret bool) { iter.skipUntilBreak() return false default: - iter.ReportError("ReadBool", "expect t or f") + iter.reportError("ReadBool", "expect t or f") return } } +// ReadBase64 reads a json object as Base64 in byte slice func (iter *Iterator) ReadBase64() (ret []byte) { src := iter.readStringAsBytes() if iter.Error != nil { @@ -656,7 +673,9 @@ func (iter *Iterator) ReadBase64() (ret []byte) { return ret[:n] } -func (iter *Iterator) ReadNull() (ret bool) { +// 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.skipUntilBreak() @@ -666,6 +685,7 @@ func (iter *Iterator) ReadNull() (ret bool) { return false } +// Skip skips a json object and positions to relatively the next json object func (iter *Iterator) Skip() { c := iter.nextToken() switch c { @@ -678,7 +698,7 @@ func (iter *Iterator) Skip() { case '{': iter.skipObject() default: - iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c)) + iter.reportError("Skip", fmt.Sprintf("do not know how to skip: %v", c)) return } } @@ -700,7 +720,6 @@ func (iter *Iterator) skipString() { } } - // 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. @@ -711,22 +730,21 @@ func (iter *Iterator) findStringEnd() (int, bool) { if c == '"' { if !escaped { return i + 1, false - } else { - 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-- + } + 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 @@ -751,7 +769,6 @@ func (iter *Iterator) findStringEnd() (int, bool) { return -1, true // end with \ } - func (iter *Iterator) findStringEndWithoutEscape() int { for i := iter.head; i < iter.tail; i++ { c := iter.buf[i] @@ -785,7 +802,7 @@ func (iter *Iterator) skipArray() { } } } - if (!iter.loadMore()) { + if !iter.loadMore() { return } } @@ -812,7 +829,7 @@ func (iter *Iterator) skipObject() { } } } - if (!iter.loadMore()) { + if !iter.loadMore() { return } } @@ -829,7 +846,7 @@ func (iter *Iterator) skipUntilBreak() { return } } - if (!iter.loadMore()) { + if !iter.loadMore() { return } } diff --git a/jsoniter_any_test.go b/jsoniter_any_test.go index 2d17e1c0..fe98f7b8 100644 --- a/jsoniter_any_test.go +++ b/jsoniter_any_test.go @@ -1,8 +1,8 @@ package jsoniter import ( - "testing" "fmt" + "testing" ) func Test_read_string_as_any(t *testing.T) { diff --git a/jsoniter_array_test.go b/jsoniter_array_test.go index 5a988d1b..368b1b06 100644 --- a/jsoniter_array_test.go +++ b/jsoniter_array_test.go @@ -1,8 +1,8 @@ package jsoniter import ( - "testing" "encoding/json" + "testing" ) func Test_empty_array(t *testing.T) { @@ -135,4 +135,4 @@ func Benchmark_json_array(b *testing.B) { result := []interface{}{} json.Unmarshal([]byte(`[1,2,3]`), &result) } -} \ No newline at end of file +} diff --git a/jsoniter_base64_test.go b/jsoniter_base64_test.go index 7a853005..61d9da8a 100644 --- a/jsoniter_base64_test.go +++ b/jsoniter_base64_test.go @@ -1,8 +1,8 @@ package jsoniter import ( - "testing" "bytes" + "testing" ) func Test_read_base64(t *testing.T) { @@ -12,7 +12,6 @@ func Test_read_base64(t *testing.T) { } } - func Test_bad_case(t *testing.T) { // field := *(*string)(unsafe.Pointer(&str)) // caused this issue @@ -40,4 +39,4 @@ func Test_bad_case(t *testing.T) { if count != 32 { t.Fatal(count) } -} \ No newline at end of file +} diff --git a/jsoniter_customize_test.go b/jsoniter_customize_test.go index bf49463a..dace70ca 100644 --- a/jsoniter_customize_test.go +++ b/jsoniter_customize_test.go @@ -1,11 +1,11 @@ package jsoniter import ( + "reflect" + "strconv" "testing" "time" "unsafe" - "strconv" - "reflect" ) func Test_customize_type_decoder(t *testing.T) { @@ -17,7 +17,7 @@ func Test_customize_type_decoder(t *testing.T) { } *((*time.Time)(ptr)) = t }) - defer ClearDecoders() + defer CleanDecoders() val := time.Time{} err := Unmarshal([]byte(`"2016-12-05 08:43:28"`), &val) if err != nil { @@ -37,7 +37,7 @@ func Test_customize_field_decoder(t *testing.T) { RegisterFieldDecoder("jsoniter.Tom", "field1", func(ptr unsafe.Pointer, iter *Iterator) { *((*string)(ptr)) = strconv.Itoa(iter.ReadInt()) }) - defer ClearDecoders() + defer CleanDecoders() tom := Tom{} err := Unmarshal([]byte(`{"field1": 100}`), &tom) if err != nil { @@ -51,7 +51,7 @@ type TestObject1 struct { func Test_customize_field_by_extension(t *testing.T) { RegisterExtension(func(type_ reflect.Type, field *reflect.StructField) ([]string, DecoderFunc) { - if (type_.String() == "jsoniter.TestObject1" && field.Name == "field1") { + if type_.String() == "jsoniter.TestObject1" && field.Name == "field1" { return []string{"field-1"}, func(ptr unsafe.Pointer, iter *Iterator) { *((*string)(ptr)) = strconv.Itoa(iter.ReadInt()) } @@ -66,4 +66,4 @@ func Test_customize_field_by_extension(t *testing.T) { if obj.field1 != "100" { t.Fatal(obj.field1) } -} \ No newline at end of file +} diff --git a/jsoniter_demo_test.go b/jsoniter_demo_test.go index e631240d..00c57a91 100644 --- a/jsoniter_demo_test.go +++ b/jsoniter_demo_test.go @@ -1,8 +1,8 @@ package jsoniter import ( - "testing" "fmt" + "testing" ) func Test_bind_api_demo(t *testing.T) { @@ -39,16 +39,16 @@ func Test_deep_nested_any_api(t *testing.T) { } type User struct { - userId int - name string - tags []string + userID int + name string + tags []string } func Test_iterator_and_bind_api(t *testing.T) { iter := ParseString(`[123, {"name": "taowen", "tags": ["crazy", "hacker"]}]`) user := User{} iter.ReadArray() - user.userId = iter.ReadInt() + user.userID = iter.ReadInt() iter.ReadArray() iter.Read(&user) iter.ReadArray() // array end diff --git a/jsoniter_find_end_test.go b/jsoniter_find_end_test.go index 9e04bfbe..c85ddbdc 100644 --- a/jsoniter_find_end_test.go +++ b/jsoniter_find_end_test.go @@ -1,8 +1,8 @@ package jsoniter import ( - "testing" "io" + "testing" ) func Test_string_end(t *testing.T) { diff --git a/jsoniter_float_test.go b/jsoniter_float_test.go index d9f746ff..3941d0e2 100644 --- a/jsoniter_float_test.go +++ b/jsoniter_float_test.go @@ -1,9 +1,9 @@ package jsoniter import ( - "testing" "encoding/json" "fmt" + "testing" ) func Test_float64_0(t *testing.T) { @@ -44,4 +44,4 @@ func Benchmark_json_float(b *testing.B) { result := float64(0) json.Unmarshal([]byte(`1.1`), &result) } -} \ No newline at end of file +} diff --git a/jsoniter_int_test.go b/jsoniter_int_test.go index 5d853a89..6695a3de 100644 --- a/jsoniter_int_test.go +++ b/jsoniter_int_test.go @@ -1,9 +1,9 @@ package jsoniter import ( - "testing" "bytes" "encoding/json" + "testing" ) func Test_uint64_0(t *testing.T) { @@ -80,4 +80,4 @@ func Benchmark_json_int(b *testing.B) { result := int64(0) json.Unmarshal([]byte(`-100`), &result) } -} \ No newline at end of file +} diff --git a/jsoniter_io_test.go b/jsoniter_io_test.go index 06e07945..30ffd452 100644 --- a/jsoniter_io_test.go +++ b/jsoniter_io_test.go @@ -1,9 +1,9 @@ package jsoniter import ( - "testing" "bytes" "io" + "testing" ) func Test_read_by_one(t *testing.T) { @@ -81,4 +81,4 @@ func Test_read_until_eof(t *testing.T) { if iter.Error != io.EOF { t.Fatal(iter.Error) } -} \ No newline at end of file +} diff --git a/jsoniter_large_file_test.go b/jsoniter_large_file_test.go index af70bf8a..1a8745ee 100644 --- a/jsoniter_large_file_test.go +++ b/jsoniter_large_file_test.go @@ -1,10 +1,10 @@ package jsoniter import ( - "testing" - "os" "encoding/json" "io/ioutil" + "os" + "testing" ) //func Test_large_file(t *testing.T) { @@ -23,7 +23,6 @@ import ( // } //} - func Benchmark_jsoniter_large_file(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { diff --git a/jsoniter_map_test.go b/jsoniter_map_test.go index b47ee572..b8f02c48 100644 --- a/jsoniter_map_test.go +++ b/jsoniter_map_test.go @@ -1,16 +1,16 @@ package jsoniter import ( - "testing" - "reflect" "fmt" + "reflect" + "testing" ) func Test_read_map(t *testing.T) { iter := ParseString(`{"hello": "world"}`) m := map[string]string{"1": "2"} iter.Read(&m) - copy(iter.buf, []byte{0,0,0,0,0,0}) + copy(iter.buf, []byte{0, 0, 0, 0, 0, 0}) if !reflect.DeepEqual(map[string]string{"1": "2", "hello": "world"}, m) { fmt.Println(iter.Error) t.Fatal(m) diff --git a/jsoniter_nested_test.go b/jsoniter_nested_test.go index dd5de8b0..984d189c 100644 --- a/jsoniter_nested_test.go +++ b/jsoniter_nested_test.go @@ -1,9 +1,9 @@ package jsoniter import ( - "testing" - "reflect" "encoding/json" + "reflect" + "testing" ) type Level1 struct { @@ -28,14 +28,14 @@ func Test_nested(t *testing.T) { case "world": l2.World = iter.ReadString() default: - iter.ReportError("bind l2", "unexpected field: " + l2Field) + iter.reportError("bind l2", "unexpected field: "+l2Field) } } l2Array = append(l2Array, l2) } l1.Hello = l2Array default: - iter.ReportError("bind l1", "unexpected field: " + l1Field) + iter.reportError("bind l1", "unexpected field: "+l1Field) } } if !reflect.DeepEqual(l1, Level1{ @@ -85,4 +85,4 @@ func Benchmark_json_nested(b *testing.B) { l1 := Level1{} json.Unmarshal([]byte(`{"hello": [{"world": "value1"}, {"world": "value2"}]}`), &l1) } -} \ No newline at end of file +} diff --git a/jsoniter_null_test.go b/jsoniter_null_test.go index cb27d41e..5e15831f 100644 --- a/jsoniter_null_test.go +++ b/jsoniter_null_test.go @@ -6,7 +6,7 @@ import ( func Test_null(t *testing.T) { iter := ParseString(`null`) - if iter.ReadNull() != true { + if iter.ReadNil() != true { t.FailNow() } } @@ -55,4 +55,4 @@ func Test_null_skip(t *testing.T) { if iter.ReadString() != "a" { t.FailNow() } -} \ No newline at end of file +} diff --git a/jsoniter_object_test.go b/jsoniter_object_test.go index 42e4dcc8..f5559755 100644 --- a/jsoniter_object_test.go +++ b/jsoniter_object_test.go @@ -1,9 +1,9 @@ package jsoniter import ( - "testing" "encoding/json" "fmt" + "testing" ) func Test_empty_object(t *testing.T) { @@ -61,7 +61,7 @@ func Test_two_field(t *testing.T) { case "field2": iter.ReadInt64() default: - iter.ReportError("bind object", "unexpected field") + iter.reportError("bind object", "unexpected field") } } } @@ -82,7 +82,7 @@ func Benchmark_jsoniter_object(b *testing.B) { case "field2": obj.Field2 = iter.ReadUint64() default: - iter.ReportError("bind object", "unexpected field") + iter.reportError("bind object", "unexpected field") } } } diff --git a/jsoniter_reflect_test.go b/jsoniter_reflect_test.go index 2f528ee1..8853f370 100644 --- a/jsoniter_reflect_test.go +++ b/jsoniter_reflect_test.go @@ -1,9 +1,9 @@ package jsoniter import ( - "testing" - "fmt" "encoding/json" + "fmt" + "testing" "unsafe" ) @@ -162,15 +162,15 @@ type StructOfString struct { func Test_reflect_struct_string(t *testing.T) { iter := ParseString(`{"field1": "hello", "field2": "world"}`) - struct_ := StructOfString{} - iter.Read(&struct_) - if struct_.field1 != "hello" { + Struct := StructOfString{} + iter.Read(&Struct) + if Struct.field1 != "hello" { fmt.Println(iter.Error) - t.Fatal(struct_.field1) + t.Fatal(Struct.field1) } - if struct_.field2 != "world" { + if Struct.field2 != "world" { fmt.Println(iter.Error) - t.Fatal(struct_.field1) + t.Fatal(Struct.field2) } } @@ -181,39 +181,39 @@ type StructOfStringPtr struct { func Test_reflect_struct_string_ptr(t *testing.T) { iter := ParseString(`{"field1": null, "field2": "world"}`) - struct_ := StructOfStringPtr{} - iter.Read(&struct_) - if struct_.field1 != nil { + Struct := StructOfStringPtr{} + iter.Read(&Struct) + if Struct.field1 != nil { fmt.Println(iter.Error) - t.Fatal(struct_.field1) + t.Fatal(Struct.field1) } - if *struct_.field2 != "world" { + if *Struct.field2 != "world" { fmt.Println(iter.Error) - t.Fatal(struct_.field2) + t.Fatal(Struct.field2) } } type StructOfTag struct { - field1 string `json:"field-1"` - field2 string `json:"-"` - field3 int `json:",string"` + Field1 string `json:"field-1"` + Field2 string `json:"-"` + Field3 int `json:",string"` } func Test_reflect_struct_tag_field(t *testing.T) { - iter := ParseString(`{"field-1": "hello", "field2": "", "field3": "100"}`) - struct_ := StructOfTag{field2: "world"} - iter.Read(&struct_) - if struct_.field1 != "hello" { + iter := ParseString(`{"field-1": "hello", "field2": "", "Field3": "100"}`) + Struct := StructOfTag{Field2: "world"} + iter.Read(&Struct) + if Struct.Field1 != "hello" { fmt.Println(iter.Error) - t.Fatal(struct_.field1) + t.Fatal(Struct.Field1) } - if struct_.field2 != "world" { + if Struct.Field2 != "world" { fmt.Println(iter.Error) - t.Fatal(struct_.field2) + t.Fatal(Struct.Field2) } - if struct_.field3 != 100 { + if Struct.Field3 != 100 { fmt.Println(iter.Error) - t.Fatal(struct_.field3) + t.Fatal(Struct.Field3) } } @@ -249,7 +249,7 @@ func Test_reflect_large_slice(t *testing.T) { } if slice[8] != 9 { fmt.Println(iter.Error) - t.Fatal(slice[1]) + t.Fatal(slice[8]) } } @@ -271,7 +271,7 @@ func Test_reflect_nested(t *testing.T) { } if slice[2].field2 != "world" { fmt.Println(iter.Error) - t.Fatal(slice[1]) + t.Fatal(slice[2]) } } @@ -281,7 +281,7 @@ func Test_reflect_base64(t *testing.T) { RegisterTypeDecoder("[]uint8", func(ptr unsafe.Pointer, iter *Iterator) { *((*[]byte)(ptr)) = iter.ReadBase64() }) - defer ClearDecoders() + defer CleanDecoders() iter.Read(&val) if "abc" != string(val) { t.Fatal(string(val)) @@ -289,22 +289,22 @@ func Test_reflect_base64(t *testing.T) { } type StructOfTagOne struct { - field1 string `json:"field1"` - field2 string `json:"field2"` - field3 int `json:"field3,string"` - field4 int `json:"field4,string"` + Field1 string `json:"field1"` + Field2 string `json:"field2"` + Field3 int `json:"field3,string"` + Field4 int `json:"field4,string"` } func Benchmark_jsoniter_reflect(b *testing.B) { b.ReportAllocs() iter := Create() - struct_ := &StructOfTagOne{} - //var struct_ *StructOfTagOne + Struct := &StructOfTagOne{} + //var Struct *StructOfTagOne input := []byte(`{"field3": "100", "field4": "100"}`) //input := []byte(`null`) for n := 0; n < b.N; n++ { iter.ResetBytes(input) - iter.Read(&struct_) + iter.Read(&Struct) } } @@ -316,9 +316,9 @@ func Benchmark_jsoniter_direct(b *testing.B) { //for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { // switch field { // case "field1": - // struct_.field1 = iter.ReadString() + // struct_.Field1 = iter.ReadString() // case "field2": - // struct_.field2 = iter.ReadString() + // struct_.Field2 = iter.ReadString() // default: // iter.Skip() // } @@ -334,9 +334,9 @@ func Benchmark_jsoniter_direct(b *testing.B) { func Benchmark_json_reflect(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { - struct_ := StructOfTagOne{} - json.Unmarshal([]byte(`{"field3": "100"}`), &struct_) + Struct := StructOfTagOne{} + json.Unmarshal([]byte(`{"field3": "100"}`), &Struct) //array := make([]string, 0, 2) //json.Unmarshal([]byte(`["hello", "world"]`), &array) } -} \ No newline at end of file +} diff --git a/jsoniter_skip_test.go b/jsoniter_skip_test.go index 8a32c228..d3726d24 100644 --- a/jsoniter_skip_test.go +++ b/jsoniter_skip_test.go @@ -1,11 +1,10 @@ package jsoniter import ( - "testing" "encoding/json" + "testing" ) - func Test_skip_number(t *testing.T) { iter := ParseString(`[-0.12, "b"]`) iter.ReadArray() @@ -148,4 +147,4 @@ func Benchmark_json_skip(b *testing.B) { result := TestResp{} json.Unmarshal(input, &result) } -} \ No newline at end of file +} diff --git a/jsoniter_string_test.go b/jsoniter_string_test.go index 47fac478..5fa042ea 100644 --- a/jsoniter_string_test.go +++ b/jsoniter_string_test.go @@ -1,9 +1,9 @@ package jsoniter import ( - "testing" "bytes" "encoding/json" + "testing" ) func Test_string_empty(t *testing.T) { @@ -121,4 +121,4 @@ func Benchmark_json_ascii(b *testing.B) { result := "" json.Unmarshal([]byte(`"hello"`), &result) } -} \ No newline at end of file +}