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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,12 @@
package jsoniter
import (
"io"
"fmt"
"unicode/utf16"
"strconv"
"unsafe"
"encoding/base64"
"fmt"
"io"
"strconv"
"unicode/utf16"
"unsafe"
)
type ValueType int
@ -30,37 +30,38 @@ func init() {
digits[i] = 255
}
for i := '0'; i <= '9'; i++ {
digits[i] = byte(i - '0');
digits[i] = byte(i - '0')
}
for i := 'a'; i <= 'f'; i++ {
digits[i] = byte((i - 'a') + 10);
digits[i] = byte((i - 'a') + 10)
}
for i := 'A'; i <= 'F'; i++ {
digits[i] = byte((i - 'A') + 10);
digits[i] = byte((i - 'A') + 10)
}
valueTypes = make([]ValueType, 256)
for i := 0; i < len(valueTypes); i++ {
valueTypes[i] = Invalid
}
valueTypes['"'] = String;
valueTypes['-'] = Number;
valueTypes['0'] = Number;
valueTypes['1'] = Number;
valueTypes['2'] = Number;
valueTypes['3'] = Number;
valueTypes['4'] = Number;
valueTypes['5'] = Number;
valueTypes['6'] = Number;
valueTypes['7'] = Number;
valueTypes['8'] = Number;
valueTypes['9'] = Number;
valueTypes['t'] = Bool;
valueTypes['f'] = Bool;
valueTypes['n'] = Null;
valueTypes['['] = Array;
valueTypes['{'] = Object;
valueTypes['"'] = String
valueTypes['-'] = Number
valueTypes['0'] = Number
valueTypes['1'] = Number
valueTypes['2'] = Number
valueTypes['3'] = Number
valueTypes['4'] = Number
valueTypes['5'] = Number
valueTypes['6'] = Number
valueTypes['7'] = Number
valueTypes['8'] = Number
valueTypes['9'] = Number
valueTypes['t'] = Bool
valueTypes['f'] = Bool
valueTypes['n'] = Null
valueTypes['['] = Array
valueTypes['{'] = Object
}
// Iterator is a fast and flexible JSON parser
type Iterator struct {
reader io.Reader
buf []byte
@ -69,37 +70,42 @@ type Iterator struct {
Error error
}
// Create creates an empty Iterator instance
func Create() *Iterator {
return &Iterator{
reader: nil,
buf: nil,
head: 0,
tail: 0,
buf: nil,
head: 0,
tail: 0,
}
}
// Parse parses a json buffer in io.Reader into an Iterator instance
func Parse(reader io.Reader, bufSize int) *Iterator {
return &Iterator{
reader: reader,
buf: make([]byte, bufSize),
head: 0,
tail: 0,
buf: make([]byte, bufSize),
head: 0,
tail: 0,
}
}
// ParseBytes parses a json byte slice into an Iterator instance
func ParseBytes(input []byte) *Iterator {
return &Iterator{
reader: nil,
buf: input,
head: 0,
tail: len(input),
buf: input,
head: 0,
tail: len(input),
}
}
// ParseString parses a json string into an Iterator instance
func ParseString(input string) *Iterator {
return ParseBytes([]byte(input))
}
// Reset can reset an Iterator instance for another json buffer in io.Reader
func (iter *Iterator) Reset(reader io.Reader) *Iterator {
iter.reader = reader
iter.head = 0
@ -107,6 +113,7 @@ func (iter *Iterator) Reset(reader io.Reader) *Iterator {
return iter
}
// ResetBytes can reset an Iterator instance for another json byte slice
func (iter *Iterator) ResetBytes(input []byte) *Iterator {
iter.reader = nil
iter.Error = nil
@ -116,10 +123,11 @@ func (iter *Iterator) ResetBytes(input []byte) *Iterator {
return iter
}
// WhatIsNext gets ValueType of relatively next json object
func (iter *Iterator) WhatIsNext() ValueType {
valueType := valueTypes[iter.nextToken()];
iter.unreadByte();
return valueType;
valueType := valueTypes[iter.nextToken()]
iter.unreadByte()
return valueType
}
func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool {
@ -144,7 +152,7 @@ func (iter *Iterator) nextToken() byte {
case ' ', '\n', '\t', '\r':
continue
}
iter.head = i+1
iter.head = i + 1
return c
}
if !iter.loadMore() {
@ -153,7 +161,7 @@ func (iter *Iterator) nextToken() byte {
}
}
func (iter *Iterator) ReportError(operation string, msg string) {
func (iter *Iterator) reportError(operation string, msg string) {
if iter.Error != nil {
return
}
@ -162,16 +170,17 @@ func (iter *Iterator) ReportError(operation string, msg string) {
peekStart = 0
}
iter.Error = fmt.Errorf("%s: %s, parsing %v ...%s... at %s", operation, msg, iter.head,
string(iter.buf[peekStart: iter.head]), string(iter.buf[0:iter.tail]))
string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
}
// CurrentBuffer gets current buffer as string
func (iter *Iterator) CurrentBuffer() string {
peekStart := iter.head - 10
if peekStart < 0 {
peekStart = 0
}
return fmt.Sprintf("parsing %v ...|%s|... at %s", iter.head,
string(iter.buf[peekStart: iter.head]), string(iter.buf[0:iter.tail]))
string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
}
func (iter *Iterator) readByte() (ret byte) {
@ -180,9 +189,8 @@ func (iter *Iterator) readByte() (ret byte) {
ret = iter.buf[iter.head]
iter.head++
return ret
} else {
return 0
}
return 0
}
ret = iter.buf[iter.head]
iter.head++
@ -200,9 +208,6 @@ func (iter *Iterator) loadMore() bool {
if err != nil {
iter.Error = err
return false
} else {
// n == 0, err == nil is not EOF
continue
}
} else {
iter.head = 0
@ -214,58 +219,63 @@ func (iter *Iterator) loadMore() bool {
func (iter *Iterator) unreadByte() {
if iter.head == 0 {
iter.ReportError("unreadByte", "unread too many bytes")
iter.reportError("unreadByte", "unread too many bytes")
return
}
iter.head -= 1
iter.head--
return
}
const maxUint64 = (1 << 64 - 1)
const cutoffUint64 = maxUint64 / 10 + 1
const maxUint32 = (1 << 32 - 1)
const cutoffUint32 = maxUint32 / 10 + 1
const maxUint64 = (1<<64 - 1)
const cutoffUint64 = maxUint64/10 + 1
const maxUint32 = (1<<32 - 1)
const cutoffUint32 = maxUint32/10 + 1
// ReadUint reads a json object as Uint
func (iter *Iterator) ReadUint() (ret uint) {
val := iter.ReadUint64()
converted := uint(val)
if uint64(converted) != val {
iter.ReportError("ReadUint", "int overflow")
iter.reportError("ReadUint", "int overflow")
return
}
return converted
}
// ReadUint8 reads a json object as Uint8
func (iter *Iterator) ReadUint8() (ret uint8) {
val := iter.ReadUint64()
converted := uint8(val)
if uint64(converted) != val {
iter.ReportError("ReadUint8", "int overflow")
iter.reportError("ReadUint8", "int overflow")
return
}
return converted
}
// ReadUint16 reads a json object as Uint16
func (iter *Iterator) ReadUint16() (ret uint16) {
val := iter.ReadUint64()
converted := uint16(val)
if uint64(converted) != val {
iter.ReportError("ReadUint16", "int overflow")
iter.reportError("ReadUint16", "int overflow")
return
}
return converted
}
// ReadUint32 reads a json object as Uint32
func (iter *Iterator) ReadUint32() (ret uint32) {
val := iter.ReadUint64()
converted := uint32(val)
if uint64(converted) != val {
iter.ReportError("ReadUint32", "int overflow")
iter.reportError("ReadUint32", "int overflow")
return
}
return converted
}
// ReadUint64 reads a json object as Uint64
func (iter *Iterator) ReadUint64() (ret uint64) {
c := iter.nextToken()
v := digits[c]
@ -273,15 +283,15 @@ func (iter *Iterator) ReadUint64() (ret uint64) {
return 0 // single zero
}
if v == 255 {
iter.ReportError("ReadUint64", "unexpected character")
iter.reportError("ReadUint64", "unexpected character")
return
}
for {
if ret >= cutoffUint64 {
iter.ReportError("ReadUint64", "overflow")
iter.reportError("ReadUint64", "overflow")
return
}
ret = ret * 10 + uint64(v)
ret = ret*10 + uint64(v)
c = iter.readByte()
v = digits[c]
if v == 255 {
@ -292,46 +302,51 @@ func (iter *Iterator) ReadUint64() (ret uint64) {
return ret
}
// ReadInt reads a json object as Int
func (iter *Iterator) ReadInt() (ret int) {
val := iter.ReadInt64()
converted := int(val)
if int64(converted) != val {
iter.ReportError("ReadInt", "int overflow")
iter.reportError("ReadInt", "int overflow")
return
}
return converted
}
// ReadInt8 reads a json object as Int8
func (iter *Iterator) ReadInt8() (ret int8) {
val := iter.ReadInt64()
converted := int8(val)
if int64(converted) != val {
iter.ReportError("ReadInt8", "int overflow")
iter.reportError("ReadInt8", "int overflow")
return
}
return converted
}
// ReadInt16 reads a json object as Int16
func (iter *Iterator) ReadInt16() (ret int16) {
val := iter.ReadInt64()
converted := int16(val)
if int64(converted) != val {
iter.ReportError("ReadInt16", "int overflow")
iter.reportError("ReadInt16", "int overflow")
return
}
return converted
}
// ReadInt32 reads a json object as Int32
func (iter *Iterator) ReadInt32() (ret int32) {
val := iter.ReadInt64()
converted := int32(val)
if int64(converted) != val {
iter.ReportError("ReadInt32", "int overflow")
iter.reportError("ReadInt32", "int overflow")
return
}
return converted
}
// ReadInt64 reads a json object as Int64
func (iter *Iterator) ReadInt64() (ret int64) {
c := iter.nextToken()
if iter.Error != nil {
@ -342,25 +357,24 @@ func (iter *Iterator) ReadInt64() (ret int64) {
if c == '-' {
n := iter.ReadUint64()
return -int64(n)
} else {
iter.unreadByte()
n := iter.ReadUint64()
return int64(n)
}
iter.unreadByte()
n := iter.ReadUint64()
return int64(n)
}
// ReadString reads a json object as String
func (iter *Iterator) ReadString() (ret string) {
return string(iter.readStringAsBytes())
}
func (iter *Iterator) readStringAsBytes() (ret []byte) {
c := iter.nextToken()
if c == '"' {
end := iter.findStringEndWithoutEscape()
if end != -1 {
// fast path: reuse the underlying buffer
ret = iter.buf[iter.head:end-1]
ret = iter.buf[iter.head : end-1]
iter.head = end
return ret
}
@ -370,7 +384,7 @@ func (iter *Iterator) readStringAsBytes() (ret []byte) {
iter.skipUntilBreak()
return
}
iter.ReportError("ReadString", `expects " or n`)
iter.reportError("ReadString", `expects " or n`)
return
}
@ -399,7 +413,7 @@ func (iter *Iterator) readStringAsBytesSlowPath() (ret []byte) {
return
}
if c != '\\' {
iter.ReportError("ReadString",
iter.reportError("ReadString",
`expects \u after utf16 surrogate, but \ not found`)
return
}
@ -408,7 +422,7 @@ func (iter *Iterator) readStringAsBytesSlowPath() (ret []byte) {
return
}
if c != 'u' {
iter.ReportError("ReadString",
iter.reportError("ReadString",
`expects \u after utf16 surrogate, but \u not found`)
return
}
@ -438,7 +452,7 @@ func (iter *Iterator) readStringAsBytesSlowPath() (ret []byte) {
case 't':
str = append(str, '\t')
default:
iter.ReportError("ReadString",
iter.reportError("ReadString",
`invalid escape char after \`)
return
}
@ -455,20 +469,20 @@ func (iter *Iterator) readU4() (ret rune) {
if iter.Error != nil {
return
}
if (c >= '0' && c <= '9') {
if c >= '0' && c <= '9' {
if ret >= cutoffUint32 {
iter.ReportError("readU4", "overflow")
iter.reportError("readU4", "overflow")
return
}
ret = ret * 16 + rune(c - '0')
} else if ((c >= 'a' && c <= 'f') ) {
ret = ret*16 + rune(c-'0')
} else if c >= 'a' && c <= 'f' {
if ret >= cutoffUint32 {
iter.ReportError("readU4", "overflow")
iter.reportError("readU4", "overflow")
return
}
ret = ret * 16 + rune(c - 'a' + 10)
ret = ret*16 + rune(c-'a'+10)
} else {
iter.ReportError("readU4", "expects 0~9 or a~f")
iter.reportError("readU4", "expects 0~9 or a~f")
return
}
}
@ -488,14 +502,14 @@ const (
mask3 = 0x0F // 0000 1111
mask4 = 0x07 // 0000 0111
rune1Max = 1 << 7 - 1
rune2Max = 1 << 11 - 1
rune3Max = 1 << 16 - 1
rune1Max = 1<<7 - 1
rune2Max = 1<<11 - 1
rune3Max = 1<<16 - 1
surrogateMin = 0xD800
surrogateMax = 0xDFFF
MaxRune = '\U0010FFFF' // Maximum valid Unicode code point.
MaxRune = '\U0010FFFF' // Maximum valid Unicode code point.
RuneError = '\uFFFD' // the "error" Rune or "Unicode replacement character"
)
@ -506,62 +520,62 @@ func appendRune(p []byte, r rune) []byte {
p = append(p, byte(r))
return p
case i <= rune2Max:
p = append(p, t2 | byte(r >> 6))
p = append(p, tx | byte(r) & maskx)
p = append(p, t2|byte(r>>6))
p = append(p, tx|byte(r)&maskx)
return p
case i > MaxRune, surrogateMin <= i && i <= surrogateMax:
r = RuneError
fallthrough
case i <= rune3Max:
p = append(p, t3 | byte(r >> 12))
p = append(p, tx | byte(r >> 6) & maskx)
p = append(p, tx | byte(r) & maskx)
p = append(p, t3|byte(r>>12))
p = append(p, tx|byte(r>>6)&maskx)
p = append(p, tx|byte(r)&maskx)
return p
default:
p = append(p, t4 | byte(r >> 18))
p = append(p, tx | byte(r >> 12) & maskx)
p = append(p, tx | byte(r >> 6) & maskx)
p = append(p, tx | byte(r) & maskx)
p = append(p, t4|byte(r>>18))
p = append(p, tx|byte(r>>12)&maskx)
p = append(p, tx|byte(r>>6)&maskx)
p = append(p, tx|byte(r)&maskx)
return p
}
}
// ReadArray reads a json object as Array
func (iter *Iterator) ReadArray() (ret bool) {
c := iter.nextToken()
if iter.Error != nil {
return
}
switch c {
case 'n': {
case 'n':
iter.skipUntilBreak()
return false // null
}
case '[': {
case '[':
c = iter.nextToken()
if iter.Error != nil {
return
}
if c == ']' {
return false
} else {
iter.unreadByte()
return true
}
}
case ']': return false
iter.unreadByte()
return true
case ']':
return false
case ',':
return true
default:
iter.ReportError("ReadArray", "expect [ or , or ] or n, but found: " + string([]byte{c}))
iter.reportError("ReadArray", "expect [ or , or ] or n, but found: "+string([]byte{c}))
return
}
}
// ReadFloat32 reads a json object as Float32
func (iter *Iterator) ReadFloat32() (ret float32) {
strBuf := [8]byte{}
str := strBuf[0:0]
hasMore := true
for(hasMore) {
for hasMore {
for i := iter.head; i < iter.tail; i++ {
c := iter.buf[i]
switch c {
@ -590,11 +604,12 @@ func (iter *Iterator) ReadFloat32() (ret float32) {
return float32(val)
}
// ReadFloat64 reads a json object as Float64
func (iter *Iterator) ReadFloat64() (ret float64) {
strBuf := [8]byte{}
str := strBuf[0:0]
hasMore := true
for(hasMore) {
for hasMore {
for i := iter.head; i < iter.tail; i++ {
c := iter.buf[i]
switch c {
@ -623,6 +638,7 @@ func (iter *Iterator) ReadFloat64() (ret float64) {
return val
}
// ReadBool reads a json object as Bool
func (iter *Iterator) ReadBool() (ret bool) {
c := iter.nextToken()
if iter.Error != nil {
@ -636,11 +652,12 @@ func (iter *Iterator) ReadBool() (ret bool) {
iter.skipUntilBreak()
return false
default:
iter.ReportError("ReadBool", "expect t or f")
iter.reportError("ReadBool", "expect t or f")
return
}
}
// ReadBase64 reads a json object as Base64 in byte slice
func (iter *Iterator) ReadBase64() (ret []byte) {
src := iter.readStringAsBytes()
if iter.Error != nil {
@ -656,7 +673,9 @@ func (iter *Iterator) ReadBase64() (ret []byte) {
return ret[:n]
}
func (iter *Iterator) ReadNull() (ret bool) {
// ReadNil reads a json object as nil and
// returns whether it's a nil or not
func (iter *Iterator) ReadNil() (ret bool) {
c := iter.nextToken()
if c == 'n' {
iter.skipUntilBreak()
@ -666,6 +685,7 @@ func (iter *Iterator) ReadNull() (ret bool) {
return false
}
// Skip skips a json object and positions to relatively the next json object
func (iter *Iterator) Skip() {
c := iter.nextToken()
switch c {
@ -678,7 +698,7 @@ func (iter *Iterator) Skip() {
case '{':
iter.skipObject()
default:
iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
iter.reportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
return
}
}
@ -700,7 +720,6 @@ func (iter *Iterator) skipString() {
}
}
// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go
// Tries to find the end of string
// Support if string contains escaped quote symbols.
@ -711,22 +730,21 @@ func (iter *Iterator) findStringEnd() (int, bool) {
if c == '"' {
if !escaped {
return i + 1, false
} else {
j := i - 1
for {
if j < iter.head || iter.buf[j] != '\\' {
// even number of backslashes
// either end of buffer, or " found
return i + 1, true
}
j--
if j < iter.head || iter.buf[j] != '\\' {
// odd number of backslashes
// it is \" or \\\"
break
}
j--
}
j := i - 1
for {
if j < iter.head || iter.buf[j] != '\\' {
// even number of backslashes
// either end of buffer, or " found
return i + 1, true
}
j--
if j < iter.head || iter.buf[j] != '\\' {
// odd number of backslashes
// it is \" or \\\"
break
}
j--
}
} else if c == '\\' {
escaped = true
@ -751,7 +769,6 @@ func (iter *Iterator) findStringEnd() (int, bool) {
return -1, true // end with \
}
func (iter *Iterator) findStringEndWithoutEscape() int {
for i := iter.head; i < iter.tail; i++ {
c := iter.buf[i]
@ -785,7 +802,7 @@ func (iter *Iterator) skipArray() {
}
}
}
if (!iter.loadMore()) {
if !iter.loadMore() {
return
}
}
@ -812,7 +829,7 @@ func (iter *Iterator) skipObject() {
}
}
}
if (!iter.loadMore()) {
if !iter.loadMore() {
return
}
}
@ -829,7 +846,7 @@ func (iter *Iterator) skipUntilBreak() {
return
}
}
if (!iter.loadMore()) {
if !iter.loadMore() {
return
}
}

View File

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

View File

@ -1,8 +1,8 @@
package jsoniter
import (
"testing"
"encoding/json"
"testing"
)
func Test_empty_array(t *testing.T) {
@ -135,4 +135,4 @@ func Benchmark_json_array(b *testing.B) {
result := []interface{}{}
json.Unmarshal([]byte(`[1,2,3]`), &result)
}
}
}

View File

@ -1,8 +1,8 @@
package jsoniter
import (
"testing"
"bytes"
"testing"
)
func Test_read_base64(t *testing.T) {
@ -12,7 +12,6 @@ func Test_read_base64(t *testing.T) {
}
}
func Test_bad_case(t *testing.T) {
// field := *(*string)(unsafe.Pointer(&str))
// caused this issue
@ -40,4 +39,4 @@ func Test_bad_case(t *testing.T) {
if count != 32 {
t.Fatal(count)
}
}
}

View File

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

View File

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

View File

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

View File

@ -1,9 +1,9 @@
package jsoniter
import (
"testing"
"encoding/json"
"fmt"
"testing"
)
func Test_float64_0(t *testing.T) {
@ -44,4 +44,4 @@ func Benchmark_json_float(b *testing.B) {
result := float64(0)
json.Unmarshal([]byte(`1.1`), &result)
}
}
}

View File

@ -1,9 +1,9 @@
package jsoniter
import (
"testing"
"bytes"
"encoding/json"
"testing"
)
func Test_uint64_0(t *testing.T) {
@ -80,4 +80,4 @@ func Benchmark_json_int(b *testing.B) {
result := int64(0)
json.Unmarshal([]byte(`-100`), &result)
}
}
}

View File

@ -1,9 +1,9 @@
package jsoniter
import (
"testing"
"bytes"
"io"
"testing"
)
func Test_read_by_one(t *testing.T) {
@ -81,4 +81,4 @@ func Test_read_until_eof(t *testing.T) {
if iter.Error != io.EOF {
t.Fatal(iter.Error)
}
}
}

View File

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

View File

@ -1,16 +1,16 @@
package jsoniter
import (
"testing"
"reflect"
"fmt"
"reflect"
"testing"
)
func Test_read_map(t *testing.T) {
iter := ParseString(`{"hello": "world"}`)
m := map[string]string{"1": "2"}
iter.Read(&m)
copy(iter.buf, []byte{0,0,0,0,0,0})
copy(iter.buf, []byte{0, 0, 0, 0, 0, 0})
if !reflect.DeepEqual(map[string]string{"1": "2", "hello": "world"}, m) {
fmt.Println(iter.Error)
t.Fatal(m)

View File

@ -1,9 +1,9 @@
package jsoniter
import (
"testing"
"reflect"
"encoding/json"
"reflect"
"testing"
)
type Level1 struct {
@ -28,14 +28,14 @@ func Test_nested(t *testing.T) {
case "world":
l2.World = iter.ReadString()
default:
iter.ReportError("bind l2", "unexpected field: " + l2Field)
iter.reportError("bind l2", "unexpected field: "+l2Field)
}
}
l2Array = append(l2Array, l2)
}
l1.Hello = l2Array
default:
iter.ReportError("bind l1", "unexpected field: " + l1Field)
iter.reportError("bind l1", "unexpected field: "+l1Field)
}
}
if !reflect.DeepEqual(l1, Level1{
@ -85,4 +85,4 @@ func Benchmark_json_nested(b *testing.B) {
l1 := Level1{}
json.Unmarshal([]byte(`{"hello": [{"world": "value1"}, {"world": "value2"}]}`), &l1)
}
}
}

View File

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

View File

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

View File

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

View File

@ -1,11 +1,10 @@
package jsoniter
import (
"testing"
"encoding/json"
"testing"
)
func Test_skip_number(t *testing.T) {
iter := ParseString(`[-0.12, "b"]`)
iter.ReadArray()
@ -148,4 +147,4 @@ func Benchmark_json_skip(b *testing.B) {
result := TestResp{}
json.Unmarshal(input, &result)
}
}
}

View File

@ -1,9 +1,9 @@
package jsoniter
import (
"testing"
"bytes"
"encoding/json"
"testing"
)
func Test_string_empty(t *testing.T) {
@ -121,4 +121,4 @@ func Benchmark_json_ascii(b *testing.B) {
result := ""
json.Unmarshal([]byte(`"hello"`), &result)
}
}
}