1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-17 11:26:35 +02:00

Formated, doced. Also fixed few minor bugs.

This commit is contained in:
SuperFashi 2017-01-05 21:23:08 +08:00
parent 97849e019f
commit d63a00f0bf
24 changed files with 438 additions and 402 deletions

View File

@ -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) 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? # Why jsoniter?
@ -37,7 +39,7 @@ import "github.com/json-iterator/go"
iter := ParseString(`[0, [1, 2], [3, 4], 5]`) iter := ParseString(`[0, [1, 2], [3, 4], 5]`)
count := 0 count := 0
for iter.ReadArray() { for iter.ReadArray() {
iter.skip() iter.Skip()
count++ count++
} }
fmt.Println(count) // 4 fmt.Println(count) // 4

View File

@ -1,8 +1,8 @@
package jsoniter package jsoniter
import ( import (
"testing"
"fmt" "fmt"
"testing"
) )
func Test_get_from_map(t *testing.T) { func Test_get_from_map(t *testing.T) {
@ -36,7 +36,7 @@ func Test_is_null(t *testing.T) {
any := Any{val: []interface{}{ any := Any{val: []interface{}{
1, 2, 3, 1, 2, 3,
}} }}
if any.IsNull() != false { if any.IsNil() != false {
t.FailNow() t.FailNow()
} }
} }

View File

@ -2,8 +2,7 @@ package jsoniter
import "io" import "io"
// adapt to json/encoding api // Unmarshal adapts to json/encoding APIs
func Unmarshal(data []byte, v interface{}) error { func Unmarshal(data []byte, v interface{}) error {
iter := ParseBytes(data) iter := ParseBytes(data)
iter.Read(v) iter.Read(v)

View File

@ -6,104 +6,109 @@ import (
"strconv" "strconv"
) )
// Any API is for maximum flexibility
type Any struct { type Any struct {
val interface{} val interface{}
Error error Error error
LastAccessed interface{} LastAccessed interface{}
} }
// MakeAny creates Any instance
func MakeAny(val interface{}) *Any { func MakeAny(val interface{}) *Any {
return &Any{val, nil, nil} return &Any{val, nil, nil}
} }
// Get extracts a json object from Any
func (any *Any) Get(keys ...interface{}) interface{} { func (any *Any) Get(keys ...interface{}) interface{} {
ret, err := getPath(any.val, keys...) ret, err := getPath(any.val, keys...)
any.LastAccessed = ret any.LastAccessed = ret
if err != nil { if err != nil {
any.Error = err any.Error = err
return ""; return ""
} }
return ret return ret
} }
// GetValueType gets type of a value
func (any *Any) GetValueType(keys ...interface{}) ValueType { func (any *Any) GetValueType(keys ...interface{}) ValueType {
ret, err := getPath(any.val, keys...) ret, err := getPath(any.val, keys...)
any.LastAccessed = ret any.LastAccessed = ret
if err != nil { if err != nil {
any.Error = err any.Error = err
return Invalid; return Invalid
} }
switch reflect.TypeOf(ret).Kind() { switch reflect.TypeOf(ret).Kind() {
case reflect.Uint8: case reflect.Uint8:
return Number; return Number
case reflect.Int8: case reflect.Int8:
return Number; return Number
case reflect.Uint16: case reflect.Uint16:
return Number; return Number
case reflect.Int16: case reflect.Int16:
return Number; return Number
case reflect.Uint32: case reflect.Uint32:
return Number; return Number
case reflect.Int32: case reflect.Int32:
return Number; return Number
case reflect.Uint64: case reflect.Uint64:
return Number; return Number
case reflect.Int64: case reflect.Int64:
return Number; return Number
case reflect.Int: case reflect.Int:
return Number; return Number
case reflect.Uint: case reflect.Uint:
return Number; return Number
case reflect.Float32: case reflect.Float32:
return Number; return Number
case reflect.Float64: case reflect.Float64:
return Number; return Number
case reflect.String: case reflect.String:
return String; return String
case reflect.Bool: case reflect.Bool:
return Bool; return Bool
case reflect.Array: case reflect.Array:
return Array; return Array
case reflect.Struct: case reflect.Struct:
return Object; return Object
default: default:
return Invalid return Invalid
} }
} }
// ToString converts a json object to string
func (any *Any) ToString(keys ...interface{}) string { func (any *Any) ToString(keys ...interface{}) string {
ret, err := getPath(any.val, keys...) ret, err := getPath(any.val, keys...)
any.LastAccessed = ret any.LastAccessed = ret
if err != nil { if err != nil {
any.Error = err any.Error = err
return ""; return ""
} }
switch ret := ret.(type) { switch ret := ret.(type) {
case uint8: case uint8:
return strconv.FormatInt(int64(ret), 10); return strconv.FormatInt(int64(ret), 10)
case int8: case int8:
return strconv.FormatInt(int64(ret), 10); return strconv.FormatInt(int64(ret), 10)
case uint16: case uint16:
return strconv.FormatInt(int64(ret), 10); return strconv.FormatInt(int64(ret), 10)
case int16: case int16:
return strconv.FormatInt(int64(ret), 10); return strconv.FormatInt(int64(ret), 10)
case uint32: case uint32:
return strconv.FormatInt(int64(ret), 10); return strconv.FormatInt(int64(ret), 10)
case int32: case int32:
return strconv.FormatInt(int64(ret), 10); return strconv.FormatInt(int64(ret), 10)
case uint64: case uint64:
return strconv.FormatUint(uint64(ret), 10); return strconv.FormatUint(uint64(ret), 10)
case int64: case int64:
return strconv.FormatInt(int64(ret), 10); return strconv.FormatInt(int64(ret), 10)
case int: case int:
return strconv.FormatInt(int64(ret), 10); return strconv.FormatInt(int64(ret), 10)
case uint: case uint:
return strconv.FormatInt(int64(ret), 10); return strconv.FormatInt(int64(ret), 10)
case float32: case float32:
return strconv.FormatFloat(float64(ret), 'E', -1, 32); return strconv.FormatFloat(float64(ret), 'E', -1, 32)
case float64: case float64:
return strconv.FormatFloat(ret, 'E', -1, 64); return strconv.FormatFloat(ret, 'E', -1, 64)
case string: case string:
return ret return ret
default: 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 { func (any *Any) ToUint8(keys ...interface{}) uint8 {
ret, err := getPathAsInt64(any, keys...) ret, err := getPathAsInt64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return uint8(ret) return uint8(ret)
} }
// ToInt8 converts a json object to Int8
func (any *Any) ToInt8(keys ...interface{}) int8 { func (any *Any) ToInt8(keys ...interface{}) int8 {
ret, err := getPathAsInt64(any, keys...) ret, err := getPathAsInt64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return int8(ret) return int8(ret)
} }
// ToUint16 converts a json object to Uint16
func (any *Any) ToUint16(keys ...interface{}) uint16 { func (any *Any) ToUint16(keys ...interface{}) uint16 {
ret, err := getPathAsInt64(any, keys...) ret, err := getPathAsInt64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return uint16(ret) return uint16(ret)
} }
// ToInt16 converts a json object to Int16
func (any *Any) ToInt16(keys ...interface{}) int16 { func (any *Any) ToInt16(keys ...interface{}) int16 {
ret, err := getPathAsInt64(any, keys...) ret, err := getPathAsInt64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return int16(ret) return int16(ret)
} }
// ToUint32 converts a json object to Uint32
func (any *Any) ToUint32(keys ...interface{}) uint32 { func (any *Any) ToUint32(keys ...interface{}) uint32 {
ret, err := getPathAsInt64(any, keys...) ret, err := getPathAsInt64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return uint32(ret) return uint32(ret)
} }
// ToInt32 converts a json object to Int32
func (any *Any) ToInt32(keys ...interface{}) int32 { func (any *Any) ToInt32(keys ...interface{}) int32 {
ret, err := getPathAsInt64(any, keys...) ret, err := getPathAsInt64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return int32(ret) return int32(ret)
} }
// ToUint64 converts a json object to Uint64
func (any *Any) ToUint64(keys ...interface{}) uint64 { func (any *Any) ToUint64(keys ...interface{}) uint64 {
ret, err := getPathAsUint64(any, keys...) ret, err := getPathAsUint64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return uint64(ret) return uint64(ret)
} }
// ToInt64 converts a json object to Int64
func (any *Any) ToInt64(keys ...interface{}) int64 { func (any *Any) ToInt64(keys ...interface{}) int64 {
ret, err := getPathAsInt64(any, keys...) ret, err := getPathAsInt64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return int64(ret) return int64(ret)
} }
// ToInt converts a json object to Int
func (any *Any) ToInt(keys ...interface{}) int { func (any *Any) ToInt(keys ...interface{}) int {
ret, err := getPathAsInt64(any, keys...) ret, err := getPathAsInt64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return int(ret) return int(ret)
} }
// ToUint converts a json object to Uint
func (any *Any) ToUint(keys ...interface{}) uint { func (any *Any) ToUint(keys ...interface{}) uint {
ret, err := getPathAsInt64(any, keys...) ret, err := getPathAsInt64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return uint(ret) return uint(ret)
} }
// ToFloat32 converts a json object to Float32
func (any *Any) ToFloat32(keys ...interface{}) float32 { func (any *Any) ToFloat32(keys ...interface{}) float32 {
ret, err := getPathAsFloat64(any, keys...) ret, err := getPathAsFloat64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return float32(ret) return float32(ret)
} }
// ToFloat64 converts a json object to Float64
func (any *Any) ToFloat64(keys ...interface{}) float64 { func (any *Any) ToFloat64(keys ...interface{}) float64 {
ret, err := getPathAsFloat64(any, keys...) ret, err := getPathAsFloat64(any, keys...)
if err != nil { if err != nil {
any.Error = err any.Error = err
return 0; return 0
} }
return ret return ret
} }
// ToBool converts a json object to Bool
func (any *Any) ToBool(keys ...interface{}) bool { func (any *Any) ToBool(keys ...interface{}) bool {
ret, err := getPath(any.val, keys...) ret, err := getPath(any.val, keys...)
any.LastAccessed = ret any.LastAccessed = ret
if err != nil { if err != nil {
any.Error = err any.Error = err
return false; return false
} }
typedRet, ok := ret.(bool) typedRet, ok := ret.(bool)
if !ok { if !ok {
any.Error = fmt.Errorf("%v is not bool", ret) any.Error = fmt.Errorf("%v is not bool", ret)
return false; return false
} }
return typedRet 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...) ret, err := getPath(any.val, keys...)
any.LastAccessed = ret any.LastAccessed = ret
if err != nil { if err != nil {
any.Error = err any.Error = err
return false; return false
} }
return reflect.ValueOf(ret).IsNil() return reflect.ValueOf(ret).IsNil()
} }
@ -253,35 +272,35 @@ func getPathAsInt64(any *Any, keys ...interface{}) (int64, error) {
} }
switch ret := ret.(type) { switch ret := ret.(type) {
case uint8: case uint8:
return int64(ret), nil; return int64(ret), nil
case int8: case int8:
return int64(ret), nil; return int64(ret), nil
case uint16: case uint16:
return int64(ret), nil; return int64(ret), nil
case int16: case int16:
return int64(ret), nil; return int64(ret), nil
case uint32: case uint32:
return int64(ret), nil; return int64(ret), nil
case int32: case int32:
return int64(ret), nil; return int64(ret), nil
case uint64: case uint64:
return int64(ret), nil; return int64(ret), nil
case int64: case int64:
return int64(ret), nil; return int64(ret), nil
case int: case int:
return int64(ret), nil; return int64(ret), nil
case uint: case uint:
return int64(ret), nil; return int64(ret), nil
case float32: case float32:
return int64(ret), nil; return int64(ret), nil
case float64: case float64:
return int64(ret), nil; return int64(ret), nil
case string: case string:
intVal, err := strconv.ParseInt(ret, 10, 64) intVal, err := strconv.ParseInt(ret, 10, 64)
if err != nil { if err != nil {
return 0, err return 0, err
} }
return intVal, nil; return intVal, nil
default: default:
return 0, fmt.Errorf("%v is not number", ret) 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) { switch ret := ret.(type) {
case uint8: case uint8:
return uint64(ret), nil; return uint64(ret), nil
case int8: case int8:
return uint64(ret), nil; return uint64(ret), nil
case uint16: case uint16:
return uint64(ret), nil; return uint64(ret), nil
case int16: case int16:
return uint64(ret), nil; return uint64(ret), nil
case uint32: case uint32:
return uint64(ret), nil; return uint64(ret), nil
case int32: case int32:
return uint64(ret), nil; return uint64(ret), nil
case uint64: case uint64:
return uint64(ret), nil; return uint64(ret), nil
case int64: case int64:
return uint64(ret), nil; return uint64(ret), nil
case int: case int:
return uint64(ret), nil; return uint64(ret), nil
case uint: case uint:
return uint64(ret), nil; return uint64(ret), nil
case float32: case float32:
return uint64(ret), nil; return uint64(ret), nil
case float64: case float64:
return uint64(ret), nil; return uint64(ret), nil
case string: case string:
intVal, err := strconv.ParseUint(ret, 10, 64) intVal, err := strconv.ParseUint(ret, 10, 64)
if err != nil { if err != nil {
return 0, err return 0, err
} }
return intVal, nil; return intVal, nil
default: default:
return 0, fmt.Errorf("%v is not number", ret) 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) { switch ret := ret.(type) {
case uint8: case uint8:
return float64(ret), nil; return float64(ret), nil
case int8: case int8:
return float64(ret), nil; return float64(ret), nil
case uint16: case uint16:
return float64(ret), nil; return float64(ret), nil
case int16: case int16:
return float64(ret), nil; return float64(ret), nil
case uint32: case uint32:
return float64(ret), nil; return float64(ret), nil
case int32: case int32:
return float64(ret), nil; return float64(ret), nil
case uint64: case uint64:
return float64(ret), nil; return float64(ret), nil
case int64: case int64:
return float64(ret), nil; return float64(ret), nil
case int: case int:
return float64(ret), nil; return float64(ret), nil
case uint: case uint:
return float64(ret), nil; return float64(ret), nil
case float32: case float32:
return float64(ret), nil; return float64(ret), nil
case float64: case float64:
return float64(ret), nil; return float64(ret), nil
case string: case string:
floatVal, err := strconv.ParseFloat(ret, 64) floatVal, err := strconv.ParseFloat(ret, 64)
if err != nil { if err != nil {
return 0, err return 0, err
} }
return floatVal, nil; return floatVal, nil
default: default:
return 0, fmt.Errorf("%v is not number", ret) return 0, fmt.Errorf("%v is not number", ret)
} }
} }
func getPath(val interface{}, keys ...interface{}) (interface{}, error) { func getPath(val interface{}, keys ...interface{}) (interface{}, error) {
if (len(keys) == 0) { if len(keys) == 0 {
return val, nil; return val, nil
} }
switch key := keys[0].(type) { switch key := keys[0].(type) {
case string: case string:
@ -395,9 +414,8 @@ func getPath(val interface{}, keys ...interface{}) (interface{}, error) {
copy(nextKeys, keys[1:]) copy(nextKeys, keys[1:])
return getPath(nextVal, nextKeys...) return getPath(nextVal, nextKeys...)
default: 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) { func getFromMap(val interface{}, key string) (interface{}, error) {

View File

@ -2,20 +2,20 @@ package jsoniter
import "unsafe" import "unsafe"
// ReadObject is a implemented iterator for json
func (iter *Iterator) ReadObject() (ret string) { func (iter *Iterator) ReadObject() (ret string) {
c := iter.nextToken() c := iter.nextToken()
if iter.Error != nil { if iter.Error != nil {
return return
} }
switch c { switch c {
case 'n': { case 'n':
iter.skipUntilBreak() iter.skipUntilBreak()
if iter.Error != nil { if iter.Error != nil {
return return
} }
return "" // null return "" // null
} case '{':
case '{': {
c = iter.nextToken() c = iter.nextToken()
if iter.Error != nil { if iter.Error != nil {
return return
@ -27,16 +27,15 @@ func (iter *Iterator) ReadObject() (ret string) {
iter.unreadByte() iter.unreadByte()
return iter.readObjectField() return iter.readObjectField()
default: default:
iter.ReportError("ReadObject", `expect " after {`) iter.reportError("ReadObject", `expect " after {`)
return return
} }
}
case ',': case ',':
return iter.readObjectField() return iter.readObjectField()
case '}': case '}':
return "" // end of object return "" // end of object
default: default:
iter.ReportError("ReadObject", `expect { or , or } or n`) iter.reportError("ReadObject", `expect { or , or } or n`)
return return
} }
} }
@ -51,7 +50,7 @@ func (iter *Iterator) readObjectStart() bool {
iter.unreadByte() iter.unreadByte()
return true return true
} }
iter.ReportError("readObjectStart", "expect { ") iter.reportError("readObjectStart", "expect { ")
return false return false
} }
@ -59,20 +58,20 @@ func (iter *Iterator) readObjectField() (ret string) {
str := iter.readStringAsBytes() str := iter.readStringAsBytes()
if iter.skipWhitespacesWithoutLoadMore() { if iter.skipWhitespacesWithoutLoadMore() {
if ret == "" { if ret == "" {
ret = string(str); ret = string(str)
} }
if !iter.loadMore() { if !iter.loadMore() {
return return
} }
} }
if iter.buf[iter.head] != ':' { if iter.buf[iter.head] != ':' {
iter.ReportError("ReadObject", "expect : after object field") iter.reportError("ReadObject", "expect : after object field")
return return
} }
iter.head++ iter.head++
if iter.skipWhitespacesWithoutLoadMore() { if iter.skipWhitespacesWithoutLoadMore() {
if ret == "" { if ret == "" {
ret = string(str); ret = string(str)
} }
if !iter.loadMore() { if !iter.loadMore() {
return return

View File

@ -1,14 +1,14 @@
package jsoniter package jsoniter
import ( import (
"reflect"
"errors" "errors"
"fmt" "fmt"
"unsafe"
"sync/atomic"
"strings"
"io" "io"
"reflect"
"strconv" "strconv"
"strings"
"sync/atomic"
"unsafe"
) )
/* /*
@ -20,6 +20,7 @@ Reflection on value is avoided as we can, as the reflect.Value itself will alloc
For a simple struct binding, it will be reflect.Value free and allocation free 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 { type Decoder interface {
decode(ptr unsafe.Pointer, iter *Iterator) decode(ptr unsafe.Pointer, iter *Iterator)
} }
@ -129,7 +130,6 @@ func (decoder *interfaceDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*interface{})(ptr)) = iter.ReadAny().Get() *((*interface{})(ptr)) = iter.ReadAny().Get()
} }
type anyDecoder struct { type anyDecoder struct {
} }
@ -144,7 +144,7 @@ type stringNumberDecoder struct {
func (decoder *stringNumberDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { func (decoder *stringNumberDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
c := iter.nextToken() c := iter.nextToken()
if c != '"' { if c != '"' {
iter.ReportError("stringNumberDecoder", `expect "`) iter.reportError("stringNumberDecoder", `expect "`)
return return
} }
decoder.elemDecoder.decode(ptr, iter) decoder.elemDecoder.decode(ptr, iter)
@ -153,7 +153,7 @@ func (decoder *stringNumberDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
} }
c = iter.readByte() c = iter.readByte()
if c != '"' { if c != '"' {
iter.ReportError("stringNumberDecoder", `expect "`) iter.reportError("stringNumberDecoder", `expect "`)
return return
} }
} }
@ -164,7 +164,7 @@ type optionalDecoder struct {
} }
func (decoder *optionalDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { func (decoder *optionalDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
if iter.ReadNull() { if iter.ReadNil() {
*((*unsafe.Pointer)(ptr)) = nil *((*unsafe.Pointer)(ptr)) = nil
} else { } else {
if *((*unsafe.Pointer)(ptr)) == nil { if *((*unsafe.Pointer)(ptr)) == nil {
@ -180,7 +180,7 @@ func (decoder *optionalDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
} }
type generalStructDecoder struct { type generalStructDecoder struct {
type_ reflect.Type typ reflect.Type
fields map[string]*structFieldDecoder 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 { 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 skipDecoder struct {
type_ reflect.Type typ reflect.Type
} }
func (decoder *skipDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { func (decoder *skipDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
iter.Skip() iter.Skip()
if iter.Error != nil && iter.Error != io.EOF { 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 oneFieldStructDecoder struct {
type_ reflect.Type typ reflect.Type
fieldName string fieldName string
fieldDecoder *structFieldDecoder fieldDecoder *structFieldDecoder
} }
@ -224,12 +224,12 @@ func (decoder *oneFieldStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator)
} }
} }
if iter.Error != nil && iter.Error != io.EOF { 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 twoFieldsStructDecoder struct {
type_ reflect.Type typ reflect.Type
fieldName1 string fieldName1 string
fieldDecoder1 *structFieldDecoder fieldDecoder1 *structFieldDecoder
fieldName2 string fieldName2 string
@ -248,12 +248,12 @@ func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator
} }
} }
if iter.Error != nil && iter.Error != io.EOF { 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 threeFieldsStructDecoder struct {
type_ reflect.Type typ reflect.Type
fieldName1 string fieldName1 string
fieldDecoder1 *structFieldDecoder fieldDecoder1 *structFieldDecoder
fieldName2 string fieldName2 string
@ -276,12 +276,12 @@ func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterat
} }
} }
if iter.Error != nil && iter.Error != io.EOF { 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 fourFieldsStructDecoder struct {
type_ reflect.Type typ reflect.Type
fieldName1 string fieldName1 string
fieldDecoder1 *structFieldDecoder fieldDecoder1 *structFieldDecoder
fieldName2 string fieldName2 string
@ -325,7 +325,7 @@ func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterato
} }
} }
if iter.Error != nil && iter.Error != io.EOF { 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())
} }
} }
@ -494,29 +494,33 @@ func init() {
} }
type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) 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 { type funcDecoder struct {
func_ DecoderFunc fun DecoderFunc
} }
func (decoder *funcDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { func (decoder *funcDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.func_(ptr, iter) decoder.fun(ptr, iter)
} }
func RegisterTypeDecoder(type_ string, func_ DecoderFunc) { // RegisterTypeDecoder can register a type for json object
typeDecoders[type_] = &funcDecoder{func_} func RegisterTypeDecoder(typ string, fun DecoderFunc) {
typeDecoders[typ] = &funcDecoder{fun}
} }
func RegisterFieldDecoder(type_ string, field string, func_ DecoderFunc) { // RegisterFieldDecoder can register a type for json field
fieldDecoders[fmt.Sprintf("%s/%s", type_, field)] = &funcDecoder{func_} 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) { func RegisterExtension(extension ExtensionFunc) {
extensions = append(extensions, extension) extensions = append(extensions, extension)
} }
func ClearDecoders() { // CleanDecoders cleans decoders registered
func CleanDecoders() {
typeDecoders = map[string]Decoder{} typeDecoders = map[string]Decoder{}
fieldDecoders = map[string]Decoder{} fieldDecoders = map[string]Decoder{}
} }
@ -527,6 +531,7 @@ type emptyInterface struct {
word unsafe.Pointer word unsafe.Pointer
} }
// ReadAny converts a json object in a Iterator instance to Any
func (iter *Iterator) ReadAny() (ret *Any) { func (iter *Iterator) ReadAny() (ret *Any) {
valueType := iter.WhatIsNext() valueType := iter.WhatIsNext()
switch valueType { switch valueType {
@ -540,7 +545,7 @@ func (iter *Iterator) ReadAny() (ret *Any) {
return MakeAny(iter.ReadBool()) return MakeAny(iter.ReadBool())
case Array: case Array:
val := []interface{}{} val := []interface{}{}
for (iter.ReadArray()) { for iter.ReadArray() {
element := iter.ReadAny() element := iter.ReadAny()
if iter.Error != nil { if iter.Error != nil {
return return
@ -559,20 +564,18 @@ func (iter *Iterator) ReadAny() (ret *Any) {
} }
return MakeAny(val) return MakeAny(val)
default: default:
iter.ReportError("ReadAny", fmt.Sprintf("unexpected value type: %v", valueType)) iter.reportError("ReadAny", fmt.Sprintf("unexpected value type: %v", valueType))
return MakeAny(nil) return MakeAny(nil)
} }
} }
func (iter *Iterator) readNumber() (ret *Any) { func (iter *Iterator) readNumber() (ret *Any) {
strBuf := [8]byte{} strBuf := [8]byte{}
str := strBuf[0:0] str := strBuf[0:0]
hasMore := true hasMore := true
foundFloat := false foundFloat := false
foundNegative := false foundNegative := false
for(hasMore) { for hasMore {
for i := iter.head; i < iter.tail; i++ { for i := iter.head; i < iter.tail; i++ {
c := iter.buf[i] c := iter.buf[i]
switch c { switch c {
@ -630,12 +633,13 @@ func (iter *Iterator) readNumber() (ret *Any) {
return MakeAny(val) return MakeAny(val)
} }
// Read converts an Iterator instance into go interface, same as json.Unmarshal
func (iter *Iterator) Read(obj interface{}) { func (iter *Iterator) Read(obj interface{}) {
type_ := reflect.TypeOf(obj) typ := reflect.TypeOf(obj)
cacheKey := type_.Elem() cacheKey := typ.Elem()
cachedDecoder := getDecoderFromCache(cacheKey) cachedDecoder := getDecoderFromCache(cacheKey)
if cachedDecoder == nil { if cachedDecoder == nil {
decoder, err := decoderOfType(type_) decoder, err := decoderOfType(typ)
if err != nil { if err != nil {
iter.Error = err iter.Error = err
return return
@ -656,17 +660,17 @@ func (p prefix) addTo(decoder Decoder, err error) (Decoder, error) {
return decoder, err return decoder, err
} }
func decoderOfType(type_ reflect.Type) (Decoder, error) { func decoderOfType(typ reflect.Type) (Decoder, error) {
switch type_.Kind() { switch typ.Kind() {
case reflect.Ptr: case reflect.Ptr:
return prefix("ptr").addTo(decoderOfPtr(type_.Elem())) return prefix("ptr").addTo(decoderOfPtr(typ.Elem()))
default: default:
return nil, errors.New("expect ptr") return nil, errors.New("expect ptr")
} }
} }
func decoderOfPtr(type_ reflect.Type) (Decoder, error) { func decoderOfPtr(typ reflect.Type) (Decoder, error) {
typeName := type_.String() typeName := typ.String()
if typeName == "jsoniter.Any" { if typeName == "jsoniter.Any" {
return &anyDecoder{}, nil return &anyDecoder{}, nil
} }
@ -674,7 +678,7 @@ func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
if typeDecoder != nil { if typeDecoder != nil {
return typeDecoder, nil return typeDecoder, nil
} }
switch type_.Kind() { switch typ.Kind() {
case reflect.String: case reflect.String:
return &stringDecoder{}, nil return &stringDecoder{}, nil
case reflect.Int: case reflect.Int:
@ -706,39 +710,39 @@ func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
case reflect.Interface: case reflect.Interface:
return &interfaceDecoder{}, nil return &interfaceDecoder{}, nil
case reflect.Struct: case reflect.Struct:
return decoderOfStruct(type_) return decoderOfStruct(typ)
case reflect.Slice: case reflect.Slice:
return prefix("[slice]").addTo(decoderOfSlice(type_)) return prefix("[slice]").addTo(decoderOfSlice(typ))
case reflect.Map: case reflect.Map:
return prefix("[map]").addTo(decoderOfMap(type_)) return prefix("[map]").addTo(decoderOfMap(typ))
case reflect.Ptr: case reflect.Ptr:
return prefix("[optional]").addTo(decoderOfOptional(type_.Elem())) return prefix("[optional]").addTo(decoderOfOptional(typ.Elem()))
default: default:
return nil, fmt.Errorf("unsupported type: %v", type_) return nil, fmt.Errorf("unsupported type: %v", typ)
} }
} }
func decoderOfOptional(type_ reflect.Type) (Decoder, error) { func decoderOfOptional(typ reflect.Type) (Decoder, error) {
decoder, err := decoderOfPtr(type_) decoder, err := decoderOfPtr(typ)
if err != nil { if err != nil {
return nil, err 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{} fields := map[string]*structFieldDecoder{}
for i := 0; i < type_.NumField(); i++ { for i := 0; i < typ.NumField(); i++ {
field := type_.Field(i) field := typ.Field(i)
fieldDecoderKey := fmt.Sprintf("%s/%s", type_.String(), field.Name) fieldDecoderKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
var fieldNames []string var fieldNames []string
for _, extension := range extensions { for _, extension := range extensions {
alternativeFieldNames, func_ := extension(type_, &field) alternativeFieldNames, fun := extension(typ, &field)
if alternativeFieldNames != nil { if alternativeFieldNames != nil {
fieldNames = alternativeFieldNames fieldNames = alternativeFieldNames
} }
if func_ != nil { if fun != nil {
fieldDecoders[fieldDecoderKey] = &funcDecoder{func_} fieldDecoders[fieldDecoderKey] = &funcDecoder{fun}
} }
} }
decoder := fieldDecoders[fieldDecoderKey] decoder := fieldDecoders[fieldDecoderKey]
@ -771,10 +775,10 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
} }
switch len(fields) { switch len(fields) {
case 0: case 0:
return &skipDecoder{type_}, nil return &skipDecoder{typ}, nil
case 1: case 1:
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
return &oneFieldStructDecoder{type_, fieldName, fieldDecoder}, nil return &oneFieldStructDecoder{typ, fieldName, fieldDecoder}, nil
} }
case 2: case 2:
var fieldName1 string var fieldName1 string
@ -790,7 +794,7 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
fieldDecoder2 = fieldDecoder fieldDecoder2 = fieldDecoder
} }
} }
return &twoFieldsStructDecoder{type_, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2}, nil return &twoFieldsStructDecoder{typ, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2}, nil
case 3: case 3:
var fieldName1 string var fieldName1 string
var fieldName2 string var fieldName2 string
@ -810,7 +814,7 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
fieldDecoder3 = fieldDecoder fieldDecoder3 = fieldDecoder
} }
} }
return &threeFieldsStructDecoder{type_, return &threeFieldsStructDecoder{typ,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil
case 4: case 4:
var fieldName1 string var fieldName1 string
@ -836,26 +840,26 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
fieldDecoder4 = fieldDecoder fieldDecoder4 = fieldDecoder
} }
} }
return &fourFieldsStructDecoder{type_, return &fourFieldsStructDecoder{typ,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4}, nil fieldName4, fieldDecoder4}, nil
} }
return &generalStructDecoder{type_, fields}, nil return &generalStructDecoder{typ, fields}, nil
} }
func decoderOfSlice(type_ reflect.Type) (Decoder, error) { func decoderOfSlice(typ reflect.Type) (Decoder, error) {
decoder, err := decoderOfPtr(type_.Elem()) decoder, err := decoderOfPtr(typ.Elem())
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &sliceDecoder{type_, type_.Elem(), decoder}, nil return &sliceDecoder{typ, typ.Elem(), decoder}, nil
} }
func decoderOfMap(type_ reflect.Type) (Decoder, error) { func decoderOfMap(typ reflect.Type) (Decoder, error) {
decoder, err := decoderOfPtr(type_.Elem()) decoder, err := decoderOfPtr(typ.Elem())
if err != nil { if err != nil {
return nil, err return nil, err
} }
mapInterface := reflect.New(type_).Interface() mapInterface := reflect.New(typ).Interface()
return &mapDecoder{type_, type_.Elem(), decoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil return &mapDecoder{typ, typ.Elem(), decoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
} }

View File

@ -1,12 +1,12 @@
package jsoniter package jsoniter
import ( import (
"io"
"fmt"
"unicode/utf16"
"strconv"
"unsafe"
"encoding/base64" "encoding/base64"
"fmt"
"io"
"strconv"
"unicode/utf16"
"unsafe"
) )
type ValueType int type ValueType int
@ -30,37 +30,38 @@ func init() {
digits[i] = 255 digits[i] = 255
} }
for i := '0'; i <= '9'; i++ { for i := '0'; i <= '9'; i++ {
digits[i] = byte(i - '0'); digits[i] = byte(i - '0')
} }
for i := 'a'; i <= 'f'; i++ { for i := 'a'; i <= 'f'; i++ {
digits[i] = byte((i - 'a') + 10); digits[i] = byte((i - 'a') + 10)
} }
for i := 'A'; i <= 'F'; i++ { for i := 'A'; i <= 'F'; i++ {
digits[i] = byte((i - 'A') + 10); digits[i] = byte((i - 'A') + 10)
} }
valueTypes = make([]ValueType, 256) valueTypes = make([]ValueType, 256)
for i := 0; i < len(valueTypes); i++ { for i := 0; i < len(valueTypes); i++ {
valueTypes[i] = Invalid valueTypes[i] = Invalid
} }
valueTypes['"'] = String; valueTypes['"'] = String
valueTypes['-'] = Number; valueTypes['-'] = Number
valueTypes['0'] = Number; valueTypes['0'] = Number
valueTypes['1'] = Number; valueTypes['1'] = Number
valueTypes['2'] = Number; valueTypes['2'] = Number
valueTypes['3'] = Number; valueTypes['3'] = Number
valueTypes['4'] = Number; valueTypes['4'] = Number
valueTypes['5'] = Number; valueTypes['5'] = Number
valueTypes['6'] = Number; valueTypes['6'] = Number
valueTypes['7'] = Number; valueTypes['7'] = Number
valueTypes['8'] = Number; valueTypes['8'] = Number
valueTypes['9'] = Number; valueTypes['9'] = Number
valueTypes['t'] = Bool; valueTypes['t'] = Bool
valueTypes['f'] = Bool; valueTypes['f'] = Bool
valueTypes['n'] = Null; valueTypes['n'] = Null
valueTypes['['] = Array; valueTypes['['] = Array
valueTypes['{'] = Object; valueTypes['{'] = Object
} }
// Iterator is a fast and flexible JSON parser
type Iterator struct { type Iterator struct {
reader io.Reader reader io.Reader
buf []byte buf []byte
@ -69,6 +70,7 @@ type Iterator struct {
Error error Error error
} }
// Create creates an empty Iterator instance
func Create() *Iterator { func Create() *Iterator {
return &Iterator{ return &Iterator{
reader: nil, reader: nil,
@ -78,6 +80,7 @@ func Create() *Iterator {
} }
} }
// Parse parses a json buffer in io.Reader into an Iterator instance
func Parse(reader io.Reader, bufSize int) *Iterator { func Parse(reader io.Reader, bufSize int) *Iterator {
return &Iterator{ return &Iterator{
reader: reader, reader: reader,
@ -87,6 +90,7 @@ func Parse(reader io.Reader, bufSize int) *Iterator {
} }
} }
// ParseBytes parses a json byte slice into an Iterator instance
func ParseBytes(input []byte) *Iterator { func ParseBytes(input []byte) *Iterator {
return &Iterator{ return &Iterator{
reader: nil, reader: nil,
@ -96,10 +100,12 @@ func ParseBytes(input []byte) *Iterator {
} }
} }
// ParseString parses a json string into an Iterator instance
func ParseString(input string) *Iterator { func ParseString(input string) *Iterator {
return ParseBytes([]byte(input)) 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 { func (iter *Iterator) Reset(reader io.Reader) *Iterator {
iter.reader = reader iter.reader = reader
iter.head = 0 iter.head = 0
@ -107,6 +113,7 @@ func (iter *Iterator) Reset(reader io.Reader) *Iterator {
return iter return iter
} }
// ResetBytes can reset an Iterator instance for another json byte slice
func (iter *Iterator) ResetBytes(input []byte) *Iterator { func (iter *Iterator) ResetBytes(input []byte) *Iterator {
iter.reader = nil iter.reader = nil
iter.Error = nil iter.Error = nil
@ -116,10 +123,11 @@ func (iter *Iterator) ResetBytes(input []byte) *Iterator {
return iter return iter
} }
// WhatIsNext gets ValueType of relatively next json object
func (iter *Iterator) WhatIsNext() ValueType { func (iter *Iterator) WhatIsNext() ValueType {
valueType := valueTypes[iter.nextToken()]; valueType := valueTypes[iter.nextToken()]
iter.unreadByte(); iter.unreadByte()
return valueType; return valueType
} }
func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool { func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool {
@ -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 { if iter.Error != nil {
return return
} }
@ -165,6 +173,7 @@ func (iter *Iterator) ReportError(operation string, msg string) {
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 { func (iter *Iterator) CurrentBuffer() string {
peekStart := iter.head - 10 peekStart := iter.head - 10
if peekStart < 0 { if peekStart < 0 {
@ -180,9 +189,8 @@ func (iter *Iterator) readByte() (ret byte) {
ret = iter.buf[iter.head] ret = iter.buf[iter.head]
iter.head++ iter.head++
return ret return ret
} else {
return 0
} }
return 0
} }
ret = iter.buf[iter.head] ret = iter.buf[iter.head]
iter.head++ iter.head++
@ -200,9 +208,6 @@ func (iter *Iterator) loadMore() bool {
if err != nil { if err != nil {
iter.Error = err iter.Error = err
return false return false
} else {
// n == 0, err == nil is not EOF
continue
} }
} else { } else {
iter.head = 0 iter.head = 0
@ -214,10 +219,10 @@ func (iter *Iterator) loadMore() bool {
func (iter *Iterator) unreadByte() { func (iter *Iterator) unreadByte() {
if iter.head == 0 { if iter.head == 0 {
iter.ReportError("unreadByte", "unread too many bytes") iter.reportError("unreadByte", "unread too many bytes")
return return
} }
iter.head -= 1 iter.head--
return return
} }
@ -226,46 +231,51 @@ const cutoffUint64 = maxUint64 / 10 + 1
const maxUint32 = (1<<32 - 1) const maxUint32 = (1<<32 - 1)
const cutoffUint32 = maxUint32/10 + 1 const cutoffUint32 = maxUint32/10 + 1
// ReadUint reads a json object as Uint
func (iter *Iterator) ReadUint() (ret uint) { func (iter *Iterator) ReadUint() (ret uint) {
val := iter.ReadUint64() val := iter.ReadUint64()
converted := uint(val) converted := uint(val)
if uint64(converted) != val { if uint64(converted) != val {
iter.ReportError("ReadUint", "int overflow") iter.reportError("ReadUint", "int overflow")
return return
} }
return converted return converted
} }
// ReadUint8 reads a json object as Uint8
func (iter *Iterator) ReadUint8() (ret uint8) { func (iter *Iterator) ReadUint8() (ret uint8) {
val := iter.ReadUint64() val := iter.ReadUint64()
converted := uint8(val) converted := uint8(val)
if uint64(converted) != val { if uint64(converted) != val {
iter.ReportError("ReadUint8", "int overflow") iter.reportError("ReadUint8", "int overflow")
return return
} }
return converted return converted
} }
// ReadUint16 reads a json object as Uint16
func (iter *Iterator) ReadUint16() (ret uint16) { func (iter *Iterator) ReadUint16() (ret uint16) {
val := iter.ReadUint64() val := iter.ReadUint64()
converted := uint16(val) converted := uint16(val)
if uint64(converted) != val { if uint64(converted) != val {
iter.ReportError("ReadUint16", "int overflow") iter.reportError("ReadUint16", "int overflow")
return return
} }
return converted return converted
} }
// ReadUint32 reads a json object as Uint32
func (iter *Iterator) ReadUint32() (ret uint32) { func (iter *Iterator) ReadUint32() (ret uint32) {
val := iter.ReadUint64() val := iter.ReadUint64()
converted := uint32(val) converted := uint32(val)
if uint64(converted) != val { if uint64(converted) != val {
iter.ReportError("ReadUint32", "int overflow") iter.reportError("ReadUint32", "int overflow")
return return
} }
return converted return converted
} }
// ReadUint64 reads a json object as Uint64
func (iter *Iterator) ReadUint64() (ret uint64) { func (iter *Iterator) ReadUint64() (ret uint64) {
c := iter.nextToken() c := iter.nextToken()
v := digits[c] v := digits[c]
@ -273,12 +283,12 @@ func (iter *Iterator) ReadUint64() (ret uint64) {
return 0 // single zero return 0 // single zero
} }
if v == 255 { if v == 255 {
iter.ReportError("ReadUint64", "unexpected character") iter.reportError("ReadUint64", "unexpected character")
return return
} }
for { for {
if ret >= cutoffUint64 { if ret >= cutoffUint64 {
iter.ReportError("ReadUint64", "overflow") iter.reportError("ReadUint64", "overflow")
return return
} }
ret = ret*10 + uint64(v) ret = ret*10 + uint64(v)
@ -292,46 +302,51 @@ func (iter *Iterator) ReadUint64() (ret uint64) {
return ret return ret
} }
// ReadInt reads a json object as Int
func (iter *Iterator) ReadInt() (ret int) { func (iter *Iterator) ReadInt() (ret int) {
val := iter.ReadInt64() val := iter.ReadInt64()
converted := int(val) converted := int(val)
if int64(converted) != val { if int64(converted) != val {
iter.ReportError("ReadInt", "int overflow") iter.reportError("ReadInt", "int overflow")
return return
} }
return converted return converted
} }
// ReadInt8 reads a json object as Int8
func (iter *Iterator) ReadInt8() (ret int8) { func (iter *Iterator) ReadInt8() (ret int8) {
val := iter.ReadInt64() val := iter.ReadInt64()
converted := int8(val) converted := int8(val)
if int64(converted) != val { if int64(converted) != val {
iter.ReportError("ReadInt8", "int overflow") iter.reportError("ReadInt8", "int overflow")
return return
} }
return converted return converted
} }
// ReadInt16 reads a json object as Int16
func (iter *Iterator) ReadInt16() (ret int16) { func (iter *Iterator) ReadInt16() (ret int16) {
val := iter.ReadInt64() val := iter.ReadInt64()
converted := int16(val) converted := int16(val)
if int64(converted) != val { if int64(converted) != val {
iter.ReportError("ReadInt16", "int overflow") iter.reportError("ReadInt16", "int overflow")
return return
} }
return converted return converted
} }
// ReadInt32 reads a json object as Int32
func (iter *Iterator) ReadInt32() (ret int32) { func (iter *Iterator) ReadInt32() (ret int32) {
val := iter.ReadInt64() val := iter.ReadInt64()
converted := int32(val) converted := int32(val)
if int64(converted) != val { if int64(converted) != val {
iter.ReportError("ReadInt32", "int overflow") iter.reportError("ReadInt32", "int overflow")
return return
} }
return converted return converted
} }
// ReadInt64 reads a json object as Int64
func (iter *Iterator) ReadInt64() (ret int64) { func (iter *Iterator) ReadInt64() (ret int64) {
c := iter.nextToken() c := iter.nextToken()
if iter.Error != nil { if iter.Error != nil {
@ -342,18 +357,17 @@ func (iter *Iterator) ReadInt64() (ret int64) {
if c == '-' { if c == '-' {
n := iter.ReadUint64() n := iter.ReadUint64()
return -int64(n) return -int64(n)
} else { }
iter.unreadByte() iter.unreadByte()
n := iter.ReadUint64() n := iter.ReadUint64()
return int64(n) return int64(n)
} }
}
// ReadString reads a json object as String
func (iter *Iterator) ReadString() (ret string) { func (iter *Iterator) ReadString() (ret string) {
return string(iter.readStringAsBytes()) return string(iter.readStringAsBytes())
} }
func (iter *Iterator) readStringAsBytes() (ret []byte) { func (iter *Iterator) readStringAsBytes() (ret []byte) {
c := iter.nextToken() c := iter.nextToken()
if c == '"' { if c == '"' {
@ -370,7 +384,7 @@ func (iter *Iterator) readStringAsBytes() (ret []byte) {
iter.skipUntilBreak() iter.skipUntilBreak()
return return
} }
iter.ReportError("ReadString", `expects " or n`) iter.reportError("ReadString", `expects " or n`)
return return
} }
@ -399,7 +413,7 @@ func (iter *Iterator) readStringAsBytesSlowPath() (ret []byte) {
return return
} }
if c != '\\' { if c != '\\' {
iter.ReportError("ReadString", iter.reportError("ReadString",
`expects \u after utf16 surrogate, but \ not found`) `expects \u after utf16 surrogate, but \ not found`)
return return
} }
@ -408,7 +422,7 @@ func (iter *Iterator) readStringAsBytesSlowPath() (ret []byte) {
return return
} }
if c != 'u' { if c != 'u' {
iter.ReportError("ReadString", iter.reportError("ReadString",
`expects \u after utf16 surrogate, but \u not found`) `expects \u after utf16 surrogate, but \u not found`)
return return
} }
@ -438,7 +452,7 @@ func (iter *Iterator) readStringAsBytesSlowPath() (ret []byte) {
case 't': case 't':
str = append(str, '\t') str = append(str, '\t')
default: default:
iter.ReportError("ReadString", iter.reportError("ReadString",
`invalid escape char after \`) `invalid escape char after \`)
return return
} }
@ -455,20 +469,20 @@ func (iter *Iterator) readU4() (ret rune) {
if iter.Error != nil { if iter.Error != nil {
return return
} }
if (c >= '0' && c <= '9') { if c >= '0' && c <= '9' {
if ret >= cutoffUint32 { if ret >= cutoffUint32 {
iter.ReportError("readU4", "overflow") iter.reportError("readU4", "overflow")
return return
} }
ret = ret*16 + rune(c-'0') ret = ret*16 + rune(c-'0')
} else if ((c >= 'a' && c <= 'f') ) { } else if c >= 'a' && c <= 'f' {
if ret >= cutoffUint32 { if ret >= cutoffUint32 {
iter.ReportError("readU4", "overflow") iter.reportError("readU4", "overflow")
return return
} }
ret = ret*16 + rune(c-'a'+10) ret = ret*16 + rune(c-'a'+10)
} else { } else {
iter.ReportError("readU4", "expects 0~9 or a~f") iter.reportError("readU4", "expects 0~9 or a~f")
return return
} }
} }
@ -526,42 +540,42 @@ func appendRune(p []byte, r rune) []byte {
} }
} }
// ReadArray reads a json object as Array
func (iter *Iterator) ReadArray() (ret bool) { func (iter *Iterator) ReadArray() (ret bool) {
c := iter.nextToken() c := iter.nextToken()
if iter.Error != nil { if iter.Error != nil {
return return
} }
switch c { switch c {
case 'n': { case 'n':
iter.skipUntilBreak() iter.skipUntilBreak()
return false // null return false // null
} case '[':
case '[': {
c = iter.nextToken() c = iter.nextToken()
if iter.Error != nil { if iter.Error != nil {
return return
} }
if c == ']' { if c == ']' {
return false return false
} else { }
iter.unreadByte() iter.unreadByte()
return true return true
} case ']':
} return false
case ']': return false
case ',': case ',':
return true return true
default: 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 return
} }
} }
// ReadFloat32 reads a json object as Float32
func (iter *Iterator) ReadFloat32() (ret float32) { func (iter *Iterator) ReadFloat32() (ret float32) {
strBuf := [8]byte{} strBuf := [8]byte{}
str := strBuf[0:0] str := strBuf[0:0]
hasMore := true hasMore := true
for(hasMore) { for hasMore {
for i := iter.head; i < iter.tail; i++ { for i := iter.head; i < iter.tail; i++ {
c := iter.buf[i] c := iter.buf[i]
switch c { switch c {
@ -590,11 +604,12 @@ func (iter *Iterator) ReadFloat32() (ret float32) {
return float32(val) return float32(val)
} }
// ReadFloat64 reads a json object as Float64
func (iter *Iterator) ReadFloat64() (ret float64) { func (iter *Iterator) ReadFloat64() (ret float64) {
strBuf := [8]byte{} strBuf := [8]byte{}
str := strBuf[0:0] str := strBuf[0:0]
hasMore := true hasMore := true
for(hasMore) { for hasMore {
for i := iter.head; i < iter.tail; i++ { for i := iter.head; i < iter.tail; i++ {
c := iter.buf[i] c := iter.buf[i]
switch c { switch c {
@ -623,6 +638,7 @@ func (iter *Iterator) ReadFloat64() (ret float64) {
return val return val
} }
// ReadBool reads a json object as Bool
func (iter *Iterator) ReadBool() (ret bool) { func (iter *Iterator) ReadBool() (ret bool) {
c := iter.nextToken() c := iter.nextToken()
if iter.Error != nil { if iter.Error != nil {
@ -636,11 +652,12 @@ func (iter *Iterator) ReadBool() (ret bool) {
iter.skipUntilBreak() iter.skipUntilBreak()
return false return false
default: default:
iter.ReportError("ReadBool", "expect t or f") iter.reportError("ReadBool", "expect t or f")
return return
} }
} }
// ReadBase64 reads a json object as Base64 in byte slice
func (iter *Iterator) ReadBase64() (ret []byte) { func (iter *Iterator) ReadBase64() (ret []byte) {
src := iter.readStringAsBytes() src := iter.readStringAsBytes()
if iter.Error != nil { if iter.Error != nil {
@ -656,7 +673,9 @@ func (iter *Iterator) ReadBase64() (ret []byte) {
return ret[:n] 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() c := iter.nextToken()
if c == 'n' { if c == 'n' {
iter.skipUntilBreak() iter.skipUntilBreak()
@ -666,6 +685,7 @@ func (iter *Iterator) ReadNull() (ret bool) {
return false return false
} }
// Skip skips a json object and positions to relatively the next json object
func (iter *Iterator) Skip() { func (iter *Iterator) Skip() {
c := iter.nextToken() c := iter.nextToken()
switch c { switch c {
@ -678,7 +698,7 @@ func (iter *Iterator) Skip() {
case '{': case '{':
iter.skipObject() iter.skipObject()
default: 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 return
} }
} }
@ -700,7 +720,6 @@ func (iter *Iterator) skipString() {
} }
} }
// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go // adapted from: https://github.com/buger/jsonparser/blob/master/parser.go
// Tries to find the end of string // Tries to find the end of string
// Support if string contains escaped quote symbols. // Support if string contains escaped quote symbols.
@ -711,7 +730,7 @@ func (iter *Iterator) findStringEnd() (int, bool) {
if c == '"' { if c == '"' {
if !escaped { if !escaped {
return i + 1, false return i + 1, false
} else { }
j := i - 1 j := i - 1
for { for {
if j < iter.head || iter.buf[j] != '\\' { if j < iter.head || iter.buf[j] != '\\' {
@ -727,7 +746,6 @@ func (iter *Iterator) findStringEnd() (int, bool) {
} }
j-- j--
} }
}
} else if c == '\\' { } else if c == '\\' {
escaped = true escaped = true
} }
@ -751,7 +769,6 @@ func (iter *Iterator) findStringEnd() (int, bool) {
return -1, true // end with \ return -1, true // end with \
} }
func (iter *Iterator) findStringEndWithoutEscape() int { func (iter *Iterator) findStringEndWithoutEscape() int {
for i := iter.head; i < iter.tail; i++ { for i := iter.head; i < iter.tail; i++ {
c := iter.buf[i] c := iter.buf[i]
@ -785,7 +802,7 @@ func (iter *Iterator) skipArray() {
} }
} }
} }
if (!iter.loadMore()) { if !iter.loadMore() {
return return
} }
} }
@ -812,7 +829,7 @@ func (iter *Iterator) skipObject() {
} }
} }
} }
if (!iter.loadMore()) { if !iter.loadMore() {
return return
} }
} }
@ -829,7 +846,7 @@ func (iter *Iterator) skipUntilBreak() {
return return
} }
} }
if (!iter.loadMore()) { if !iter.loadMore() {
return return
} }
} }

View File

@ -1,8 +1,8 @@
package jsoniter package jsoniter
import ( import (
"testing"
"fmt" "fmt"
"testing"
) )
func Test_read_string_as_any(t *testing.T) { func Test_read_string_as_any(t *testing.T) {

View File

@ -1,8 +1,8 @@
package jsoniter package jsoniter
import ( import (
"testing"
"encoding/json" "encoding/json"
"testing"
) )
func Test_empty_array(t *testing.T) { func Test_empty_array(t *testing.T) {

View File

@ -1,8 +1,8 @@
package jsoniter package jsoniter
import ( import (
"testing"
"bytes" "bytes"
"testing"
) )
func Test_read_base64(t *testing.T) { 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) { func Test_bad_case(t *testing.T) {
// field := *(*string)(unsafe.Pointer(&str)) // field := *(*string)(unsafe.Pointer(&str))
// caused this issue // caused this issue

View File

@ -1,11 +1,11 @@
package jsoniter package jsoniter
import ( import (
"reflect"
"strconv"
"testing" "testing"
"time" "time"
"unsafe" "unsafe"
"strconv"
"reflect"
) )
func Test_customize_type_decoder(t *testing.T) { func Test_customize_type_decoder(t *testing.T) {
@ -17,7 +17,7 @@ func Test_customize_type_decoder(t *testing.T) {
} }
*((*time.Time)(ptr)) = t *((*time.Time)(ptr)) = t
}) })
defer ClearDecoders() defer CleanDecoders()
val := time.Time{} val := time.Time{}
err := Unmarshal([]byte(`"2016-12-05 08:43:28"`), &val) err := Unmarshal([]byte(`"2016-12-05 08:43:28"`), &val)
if err != nil { 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) { RegisterFieldDecoder("jsoniter.Tom", "field1", func(ptr unsafe.Pointer, iter *Iterator) {
*((*string)(ptr)) = strconv.Itoa(iter.ReadInt()) *((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
}) })
defer ClearDecoders() defer CleanDecoders()
tom := Tom{} tom := Tom{}
err := Unmarshal([]byte(`{"field1": 100}`), &tom) err := Unmarshal([]byte(`{"field1": 100}`), &tom)
if err != nil { if err != nil {
@ -51,7 +51,7 @@ type TestObject1 struct {
func Test_customize_field_by_extension(t *testing.T) { func Test_customize_field_by_extension(t *testing.T) {
RegisterExtension(func(type_ reflect.Type, field *reflect.StructField) ([]string, DecoderFunc) { 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) { return []string{"field-1"}, func(ptr unsafe.Pointer, iter *Iterator) {
*((*string)(ptr)) = strconv.Itoa(iter.ReadInt()) *((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
} }

View File

@ -1,8 +1,8 @@
package jsoniter package jsoniter
import ( import (
"testing"
"fmt" "fmt"
"testing"
) )
func Test_bind_api_demo(t *testing.T) { func Test_bind_api_demo(t *testing.T) {
@ -39,7 +39,7 @@ func Test_deep_nested_any_api(t *testing.T) {
} }
type User struct { type User struct {
userId int userID int
name string name string
tags []string tags []string
} }
@ -48,7 +48,7 @@ func Test_iterator_and_bind_api(t *testing.T) {
iter := ParseString(`[123, {"name": "taowen", "tags": ["crazy", "hacker"]}]`) iter := ParseString(`[123, {"name": "taowen", "tags": ["crazy", "hacker"]}]`)
user := User{} user := User{}
iter.ReadArray() iter.ReadArray()
user.userId = iter.ReadInt() user.userID = iter.ReadInt()
iter.ReadArray() iter.ReadArray()
iter.Read(&user) iter.Read(&user)
iter.ReadArray() // array end iter.ReadArray() // array end

View File

@ -1,8 +1,8 @@
package jsoniter package jsoniter
import ( import (
"testing"
"io" "io"
"testing"
) )
func Test_string_end(t *testing.T) { func Test_string_end(t *testing.T) {

View File

@ -1,9 +1,9 @@
package jsoniter package jsoniter
import ( import (
"testing"
"encoding/json" "encoding/json"
"fmt" "fmt"
"testing"
) )
func Test_float64_0(t *testing.T) { func Test_float64_0(t *testing.T) {

View File

@ -1,9 +1,9 @@
package jsoniter package jsoniter
import ( import (
"testing"
"bytes" "bytes"
"encoding/json" "encoding/json"
"testing"
) )
func Test_uint64_0(t *testing.T) { func Test_uint64_0(t *testing.T) {

View File

@ -1,9 +1,9 @@
package jsoniter package jsoniter
import ( import (
"testing"
"bytes" "bytes"
"io" "io"
"testing"
) )
func Test_read_by_one(t *testing.T) { func Test_read_by_one(t *testing.T) {

View File

@ -1,10 +1,10 @@
package jsoniter package jsoniter
import ( import (
"testing"
"os"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"os"
"testing"
) )
//func Test_large_file(t *testing.T) { //func Test_large_file(t *testing.T) {
@ -23,7 +23,6 @@ import (
// } // }
//} //}
func Benchmark_jsoniter_large_file(b *testing.B) { func Benchmark_jsoniter_large_file(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {

View File

@ -1,9 +1,9 @@
package jsoniter package jsoniter
import ( import (
"testing"
"reflect"
"fmt" "fmt"
"reflect"
"testing"
) )
func Test_read_map(t *testing.T) { func Test_read_map(t *testing.T) {

View File

@ -1,9 +1,9 @@
package jsoniter package jsoniter
import ( import (
"testing"
"reflect"
"encoding/json" "encoding/json"
"reflect"
"testing"
) )
type Level1 struct { type Level1 struct {
@ -28,14 +28,14 @@ func Test_nested(t *testing.T) {
case "world": case "world":
l2.World = iter.ReadString() l2.World = iter.ReadString()
default: default:
iter.ReportError("bind l2", "unexpected field: " + l2Field) iter.reportError("bind l2", "unexpected field: "+l2Field)
} }
} }
l2Array = append(l2Array, l2) l2Array = append(l2Array, l2)
} }
l1.Hello = l2Array l1.Hello = l2Array
default: default:
iter.ReportError("bind l1", "unexpected field: " + l1Field) iter.reportError("bind l1", "unexpected field: "+l1Field)
} }
} }
if !reflect.DeepEqual(l1, Level1{ if !reflect.DeepEqual(l1, Level1{

View File

@ -6,7 +6,7 @@ import (
func Test_null(t *testing.T) { func Test_null(t *testing.T) {
iter := ParseString(`null`) iter := ParseString(`null`)
if iter.ReadNull() != true { if iter.ReadNil() != true {
t.FailNow() t.FailNow()
} }
} }

View File

@ -1,9 +1,9 @@
package jsoniter package jsoniter
import ( import (
"testing"
"encoding/json" "encoding/json"
"fmt" "fmt"
"testing"
) )
func Test_empty_object(t *testing.T) { func Test_empty_object(t *testing.T) {
@ -61,7 +61,7 @@ func Test_two_field(t *testing.T) {
case "field2": case "field2":
iter.ReadInt64() iter.ReadInt64()
default: 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": case "field2":
obj.Field2 = iter.ReadUint64() obj.Field2 = iter.ReadUint64()
default: default:
iter.ReportError("bind object", "unexpected field") iter.reportError("bind object", "unexpected field")
} }
} }
} }

View File

@ -1,9 +1,9 @@
package jsoniter package jsoniter
import ( import (
"testing"
"fmt"
"encoding/json" "encoding/json"
"fmt"
"testing"
"unsafe" "unsafe"
) )
@ -162,15 +162,15 @@ type StructOfString struct {
func Test_reflect_struct_string(t *testing.T) { func Test_reflect_struct_string(t *testing.T) {
iter := ParseString(`{"field1": "hello", "field2": "world"}`) iter := ParseString(`{"field1": "hello", "field2": "world"}`)
struct_ := StructOfString{} Struct := StructOfString{}
iter.Read(&struct_) iter.Read(&Struct)
if struct_.field1 != "hello" { if Struct.field1 != "hello" {
fmt.Println(iter.Error) fmt.Println(iter.Error)
t.Fatal(struct_.field1) t.Fatal(Struct.field1)
} }
if struct_.field2 != "world" { if Struct.field2 != "world" {
fmt.Println(iter.Error) 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) { func Test_reflect_struct_string_ptr(t *testing.T) {
iter := ParseString(`{"field1": null, "field2": "world"}`) iter := ParseString(`{"field1": null, "field2": "world"}`)
struct_ := StructOfStringPtr{} Struct := StructOfStringPtr{}
iter.Read(&struct_) iter.Read(&Struct)
if struct_.field1 != nil { if Struct.field1 != nil {
fmt.Println(iter.Error) fmt.Println(iter.Error)
t.Fatal(struct_.field1) t.Fatal(Struct.field1)
} }
if *struct_.field2 != "world" { if *Struct.field2 != "world" {
fmt.Println(iter.Error) fmt.Println(iter.Error)
t.Fatal(struct_.field2) t.Fatal(Struct.field2)
} }
} }
type StructOfTag struct { type StructOfTag struct {
field1 string `json:"field-1"` Field1 string `json:"field-1"`
field2 string `json:"-"` Field2 string `json:"-"`
field3 int `json:",string"` Field3 int `json:",string"`
} }
func Test_reflect_struct_tag_field(t *testing.T) { func Test_reflect_struct_tag_field(t *testing.T) {
iter := ParseString(`{"field-1": "hello", "field2": "", "field3": "100"}`) iter := ParseString(`{"field-1": "hello", "field2": "", "Field3": "100"}`)
struct_ := StructOfTag{field2: "world"} Struct := StructOfTag{Field2: "world"}
iter.Read(&struct_) iter.Read(&Struct)
if struct_.field1 != "hello" { if Struct.Field1 != "hello" {
fmt.Println(iter.Error) fmt.Println(iter.Error)
t.Fatal(struct_.field1) t.Fatal(Struct.Field1)
} }
if struct_.field2 != "world" { if Struct.Field2 != "world" {
fmt.Println(iter.Error) fmt.Println(iter.Error)
t.Fatal(struct_.field2) t.Fatal(Struct.Field2)
} }
if struct_.field3 != 100 { if Struct.Field3 != 100 {
fmt.Println(iter.Error) 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 { if slice[8] != 9 {
fmt.Println(iter.Error) 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" { if slice[2].field2 != "world" {
fmt.Println(iter.Error) 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) { RegisterTypeDecoder("[]uint8", func(ptr unsafe.Pointer, iter *Iterator) {
*((*[]byte)(ptr)) = iter.ReadBase64() *((*[]byte)(ptr)) = iter.ReadBase64()
}) })
defer ClearDecoders() defer CleanDecoders()
iter.Read(&val) iter.Read(&val)
if "abc" != string(val) { if "abc" != string(val) {
t.Fatal(string(val)) t.Fatal(string(val))
@ -289,22 +289,22 @@ func Test_reflect_base64(t *testing.T) {
} }
type StructOfTagOne struct { type StructOfTagOne struct {
field1 string `json:"field1"` Field1 string `json:"field1"`
field2 string `json:"field2"` Field2 string `json:"field2"`
field3 int `json:"field3,string"` Field3 int `json:"field3,string"`
field4 int `json:"field4,string"` Field4 int `json:"field4,string"`
} }
func Benchmark_jsoniter_reflect(b *testing.B) { func Benchmark_jsoniter_reflect(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
iter := Create() iter := Create()
struct_ := &StructOfTagOne{} Struct := &StructOfTagOne{}
//var struct_ *StructOfTagOne //var Struct *StructOfTagOne
input := []byte(`{"field3": "100", "field4": "100"}`) input := []byte(`{"field3": "100", "field4": "100"}`)
//input := []byte(`null`) //input := []byte(`null`)
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
iter.ResetBytes(input) 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() { //for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
// switch field { // switch field {
// case "field1": // case "field1":
// struct_.field1 = iter.ReadString() // struct_.Field1 = iter.ReadString()
// case "field2": // case "field2":
// struct_.field2 = iter.ReadString() // struct_.Field2 = iter.ReadString()
// default: // default:
// iter.Skip() // iter.Skip()
// } // }
@ -334,8 +334,8 @@ func Benchmark_jsoniter_direct(b *testing.B) {
func Benchmark_json_reflect(b *testing.B) { func Benchmark_json_reflect(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
struct_ := StructOfTagOne{} Struct := StructOfTagOne{}
json.Unmarshal([]byte(`{"field3": "100"}`), &struct_) json.Unmarshal([]byte(`{"field3": "100"}`), &Struct)
//array := make([]string, 0, 2) //array := make([]string, 0, 2)
//json.Unmarshal([]byte(`["hello", "world"]`), &array) //json.Unmarshal([]byte(`["hello", "world"]`), &array)
} }

View File

@ -1,11 +1,10 @@
package jsoniter package jsoniter
import ( import (
"testing"
"encoding/json" "encoding/json"
"testing"
) )
func Test_skip_number(t *testing.T) { func Test_skip_number(t *testing.T) {
iter := ParseString(`[-0.12, "b"]`) iter := ParseString(`[-0.12, "b"]`)
iter.ReadArray() iter.ReadArray()

View File

@ -1,9 +1,9 @@
package jsoniter package jsoniter
import ( import (
"testing"
"bytes" "bytes"
"encoding/json" "encoding/json"
"testing"
) )
func Test_string_empty(t *testing.T) { func Test_string_empty(t *testing.T) {