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:
@ -383,7 +402,7 @@ func getPath(val interface{}, keys ...interface{}) (interface{}, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
nextKeys := make([]interface{}, len(keys) - 1) nextKeys := make([]interface{}, len(keys)-1)
copy(nextKeys, keys[1:]) copy(nextKeys, keys[1:])
return getPath(nextVal, nextKeys...) return getPath(nextVal, nextKeys...)
case int: case int:
@ -391,13 +410,12 @@ func getPath(val interface{}, keys ...interface{}) (interface{}, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
nextKeys := make([]interface{}, len(keys) - 1) nextKeys := make([]interface{}, len(keys)-1)
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"
) )
/* /*
@ -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 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 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 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())
} }
} }
@ -343,9 +343,9 @@ func (decoder *structFieldDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
} }
type mapDecoder struct { type mapDecoder struct {
mapType reflect.Type mapType reflect.Type
elemType reflect.Type elemType reflect.Type
elemDecoder Decoder elemDecoder Decoder
mapInterface emptyInterface mapInterface emptyInterface
} }
@ -391,30 +391,30 @@ func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
return return
} }
offset := uintptr(0) 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() { if !iter.ReadArray() {
slice.Len = 1 slice.Len = 1
return return
} }
offset += decoder.elemType.Size() 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() { if !iter.ReadArray() {
slice.Len = 2 slice.Len = 2
return return
} }
offset += decoder.elemType.Size() 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() { if !iter.ReadArray() {
slice.Len = 3 slice.Len = 3
return return
} }
offset += decoder.elemType.Size() 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 slice.Len = 4
for iter.ReadArray() { for iter.ReadArray() {
growOne(slice, decoder.sliceType, decoder.elemType) growOne(slice, decoder.sliceType, decoder.elemType)
offset += decoder.elemType.Size() 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 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,37 +70,42 @@ 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,
buf: nil, buf: nil,
head: 0, head: 0,
tail: 0, tail: 0,
} }
} }
// 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,
buf: make([]byte, bufSize), buf: make([]byte, bufSize),
head: 0, head: 0,
tail: 0, tail: 0,
} }
} }
// 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,
buf: input, buf: input,
head: 0, head: 0,
tail: len(input), tail: len(input),
} }
} }
// 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 {
@ -144,7 +152,7 @@ func (iter *Iterator) nextToken() byte {
case ' ', '\n', '\t', '\r': case ' ', '\n', '\t', '\r':
continue continue
} }
iter.head = i+1 iter.head = i + 1
return c return c
} }
if !iter.loadMore() { 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 { if iter.Error != nil {
return return
} }
@ -162,16 +170,17 @@ func (iter *Iterator) ReportError(operation string, msg string) {
peekStart = 0 peekStart = 0
} }
iter.Error = fmt.Errorf("%s: %s, parsing %v ...%s... at %s", operation, msg, iter.head, 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 { func (iter *Iterator) CurrentBuffer() string {
peekStart := iter.head - 10 peekStart := iter.head - 10
if peekStart < 0 { if peekStart < 0 {
peekStart = 0 peekStart = 0
} }
return fmt.Sprintf("parsing %v ...|%s|... at %s", iter.head, 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) { func (iter *Iterator) readByte() (ret byte) {
@ -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,58 +219,63 @@ 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
} }
const maxUint64 = (1 << 64 - 1) const maxUint64 = (1<<64 - 1)
const cutoffUint64 = maxUint64 / 10 + 1 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,15 +283,15 @@ 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)
c = iter.readByte() c = iter.readByte()
v = digits[c] v = digits[c]
if v == 255 { if v == 255 {
@ -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,25 +357,24 @@ 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()
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) { 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 == '"' {
end := iter.findStringEndWithoutEscape() end := iter.findStringEndWithoutEscape()
if end != -1 { if end != -1 {
// fast path: reuse the underlying buffer // fast path: reuse the underlying buffer
ret = iter.buf[iter.head:end-1] ret = iter.buf[iter.head : end-1]
iter.head = end iter.head = end
return ret return ret
} }
@ -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
} }
} }
@ -488,14 +502,14 @@ const (
mask3 = 0x0F // 0000 1111 mask3 = 0x0F // 0000 1111
mask4 = 0x07 // 0000 0111 mask4 = 0x07 // 0000 0111
rune1Max = 1 << 7 - 1 rune1Max = 1<<7 - 1
rune2Max = 1 << 11 - 1 rune2Max = 1<<11 - 1
rune3Max = 1 << 16 - 1 rune3Max = 1<<16 - 1
surrogateMin = 0xD800 surrogateMin = 0xD800
surrogateMax = 0xDFFF 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" 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)) p = append(p, byte(r))
return p return p
case i <= rune2Max: case i <= rune2Max:
p = append(p, t2 | byte(r >> 6)) p = append(p, t2|byte(r>>6))
p = append(p, tx | byte(r) & maskx) p = append(p, tx|byte(r)&maskx)
return p return p
case i > MaxRune, surrogateMin <= i && i <= surrogateMax: case i > MaxRune, surrogateMin <= i && i <= surrogateMax:
r = RuneError r = RuneError
fallthrough fallthrough
case i <= rune3Max: case i <= rune3Max:
p = append(p, t3 | byte(r >> 12)) p = append(p, t3|byte(r>>12))
p = append(p, tx | byte(r >> 6) & maskx) p = append(p, tx|byte(r>>6)&maskx)
p = append(p, tx | byte(r) & maskx) p = append(p, tx|byte(r)&maskx)
return p return p
default: default:
p = append(p, t4 | byte(r >> 18)) p = append(p, t4|byte(r>>18))
p = append(p, tx | byte(r >> 12) & maskx) p = append(p, tx|byte(r>>12)&maskx)
p = append(p, tx | byte(r >> 6) & maskx) p = append(p, tx|byte(r>>6)&maskx)
p = append(p, tx | byte(r) & maskx) p = append(p, tx|byte(r)&maskx)
return p return p
} }
} }
// 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()
return true
} }
} iter.unreadByte()
case ']': return false return true
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,22 +730,21 @@ 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] != '\\' {
// even number of backslashes // even number of backslashes
// either end of buffer, or " found // either end of buffer, or " found
return i + 1, true return i + 1, true
}
j--
if j < iter.head || iter.buf[j] != '\\' {
// odd number of backslashes
// it is \" or \\\"
break
}
j--
} }
j--
if j < iter.head || iter.buf[j] != '\\' {
// odd number of backslashes
// it is \" or \\\"
break
}
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,16 +39,16 @@ 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
} }
func Test_iterator_and_bind_api(t *testing.T) { 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,16 +1,16 @@
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) {
iter := ParseString(`{"hello": "world"}`) iter := ParseString(`{"hello": "world"}`)
m := map[string]string{"1": "2"} m := map[string]string{"1": "2"}
iter.Read(&m) 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) { if !reflect.DeepEqual(map[string]string{"1": "2", "hello": "world"}, m) {
fmt.Println(iter.Error) fmt.Println(iter.Error)
t.Fatal(m) t.Fatal(m)

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) {