mirror of
https://github.com/json-iterator/go.git
synced 2025-05-16 21:45:43 +02:00
remove any
This commit is contained in:
parent
9c2b1d24b3
commit
9df37bbd68
72
any_test.go
72
any_test.go
@ -1,72 +0,0 @@
|
|||||||
package jsoniter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_get_from_map(t *testing.T) {
|
|
||||||
any := Any{val: map[string]interface{}{
|
|
||||||
"hello": "world",
|
|
||||||
}}
|
|
||||||
if any.ToString("hello") != "world" {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_get_from_array(t *testing.T) {
|
|
||||||
any := Any{val: []interface{}{
|
|
||||||
"hello", "world",
|
|
||||||
}}
|
|
||||||
if any.ToString(1) != "world" {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_get_int(t *testing.T) {
|
|
||||||
any := Any{val: []interface{}{
|
|
||||||
1, 2, 3,
|
|
||||||
}}
|
|
||||||
if any.ToInt(1) != 2 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_is_null(t *testing.T) {
|
|
||||||
any := Any{val: []interface{}{
|
|
||||||
1, 2, 3,
|
|
||||||
}}
|
|
||||||
if any.IsNil() != false {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_get_bool(t *testing.T) {
|
|
||||||
any := Any{val: []interface{}{
|
|
||||||
true, true, false,
|
|
||||||
}}
|
|
||||||
if any.ToBool(1) != true {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_nested_read(t *testing.T) {
|
|
||||||
any := Any{val: []interface{}{
|
|
||||||
true, map[string]interface{}{
|
|
||||||
"hello": "world",
|
|
||||||
}, false,
|
|
||||||
}}
|
|
||||||
if any.ToString(1, "hello") != "world" {
|
|
||||||
fmt.Println(any.Error)
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_int_to_string(t *testing.T) {
|
|
||||||
any := Any{val: []interface{}{
|
|
||||||
true, 5, false,
|
|
||||||
}}
|
|
||||||
if any.ToString(1) != "5" {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
445
feature_any.go
445
feature_any.go
@ -1,445 +0,0 @@
|
|||||||
package jsoniter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Any API is for maximum flexibility
|
|
||||||
type Any struct {
|
|
||||||
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 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
|
|
||||||
}
|
|
||||||
|
|
||||||
switch reflect.TypeOf(ret).Kind() {
|
|
||||||
case reflect.Uint8:
|
|
||||||
return Number
|
|
||||||
case reflect.Int8:
|
|
||||||
return Number
|
|
||||||
case reflect.Uint16:
|
|
||||||
return Number
|
|
||||||
case reflect.Int16:
|
|
||||||
return Number
|
|
||||||
case reflect.Uint32:
|
|
||||||
return Number
|
|
||||||
case reflect.Int32:
|
|
||||||
return Number
|
|
||||||
case reflect.Uint64:
|
|
||||||
return Number
|
|
||||||
case reflect.Int64:
|
|
||||||
return Number
|
|
||||||
case reflect.Int:
|
|
||||||
return Number
|
|
||||||
case reflect.Uint:
|
|
||||||
return Number
|
|
||||||
case reflect.Float32:
|
|
||||||
return Number
|
|
||||||
case reflect.Float64:
|
|
||||||
return Number
|
|
||||||
case reflect.String:
|
|
||||||
return String
|
|
||||||
case reflect.Bool:
|
|
||||||
return Bool
|
|
||||||
case reflect.Array:
|
|
||||||
return Array
|
|
||||||
case reflect.Struct:
|
|
||||||
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 ""
|
|
||||||
}
|
|
||||||
switch ret := ret.(type) {
|
|
||||||
case uint8:
|
|
||||||
return strconv.FormatInt(int64(ret), 10)
|
|
||||||
case int8:
|
|
||||||
return strconv.FormatInt(int64(ret), 10)
|
|
||||||
case uint16:
|
|
||||||
return strconv.FormatInt(int64(ret), 10)
|
|
||||||
case int16:
|
|
||||||
return strconv.FormatInt(int64(ret), 10)
|
|
||||||
case uint32:
|
|
||||||
return strconv.FormatInt(int64(ret), 10)
|
|
||||||
case int32:
|
|
||||||
return strconv.FormatInt(int64(ret), 10)
|
|
||||||
case uint64:
|
|
||||||
return strconv.FormatUint(uint64(ret), 10)
|
|
||||||
case int64:
|
|
||||||
return strconv.FormatInt(int64(ret), 10)
|
|
||||||
case int:
|
|
||||||
return strconv.FormatInt(int64(ret), 10)
|
|
||||||
case uint:
|
|
||||||
return strconv.FormatInt(int64(ret), 10)
|
|
||||||
case float32:
|
|
||||||
return strconv.FormatFloat(float64(ret), 'E', -1, 32)
|
|
||||||
case float64:
|
|
||||||
return strconv.FormatFloat(ret, 'E', -1, 64)
|
|
||||||
case string:
|
|
||||||
return ret
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("%v", ret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 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 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 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 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 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 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 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 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 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 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 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 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
|
|
||||||
}
|
|
||||||
typedRet, ok := ret.(bool)
|
|
||||||
if !ok {
|
|
||||||
any.Error = fmt.Errorf("%v is not bool", ret)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return typedRet
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 reflect.ValueOf(ret).IsNil()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPathAsInt64(any *Any, keys ...interface{}) (int64, error) {
|
|
||||||
ret, err := getPath(any.val, keys...)
|
|
||||||
any.LastAccessed = ret
|
|
||||||
if err != nil {
|
|
||||||
any.Error = err
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
switch ret := ret.(type) {
|
|
||||||
case uint8:
|
|
||||||
return int64(ret), nil
|
|
||||||
case int8:
|
|
||||||
return int64(ret), nil
|
|
||||||
case uint16:
|
|
||||||
return int64(ret), nil
|
|
||||||
case int16:
|
|
||||||
return int64(ret), nil
|
|
||||||
case uint32:
|
|
||||||
return int64(ret), nil
|
|
||||||
case int32:
|
|
||||||
return int64(ret), nil
|
|
||||||
case uint64:
|
|
||||||
return int64(ret), nil
|
|
||||||
case int64:
|
|
||||||
return int64(ret), nil
|
|
||||||
case int:
|
|
||||||
return int64(ret), nil
|
|
||||||
case uint:
|
|
||||||
return int64(ret), nil
|
|
||||||
case float32:
|
|
||||||
return int64(ret), nil
|
|
||||||
case float64:
|
|
||||||
return int64(ret), nil
|
|
||||||
case string:
|
|
||||||
intVal, err := strconv.ParseInt(ret, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return intVal, nil
|
|
||||||
default:
|
|
||||||
return 0, fmt.Errorf("%v is not number", ret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPathAsUint64(any *Any, keys ...interface{}) (uint64, error) {
|
|
||||||
ret, err := getPath(any.val, keys...)
|
|
||||||
any.LastAccessed = ret
|
|
||||||
if err != nil {
|
|
||||||
any.Error = err
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
switch ret := ret.(type) {
|
|
||||||
case uint8:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case int8:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case uint16:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case int16:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case uint32:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case int32:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case uint64:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case int64:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case int:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case uint:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case float32:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case float64:
|
|
||||||
return uint64(ret), nil
|
|
||||||
case string:
|
|
||||||
intVal, err := strconv.ParseUint(ret, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return intVal, nil
|
|
||||||
default:
|
|
||||||
return 0, fmt.Errorf("%v is not number", ret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPathAsFloat64(any *Any, keys ...interface{}) (float64, error) {
|
|
||||||
ret, err := getPath(any.val, keys...)
|
|
||||||
any.LastAccessed = ret
|
|
||||||
if err != nil {
|
|
||||||
any.Error = err
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
switch ret := ret.(type) {
|
|
||||||
case uint8:
|
|
||||||
return float64(ret), nil
|
|
||||||
case int8:
|
|
||||||
return float64(ret), nil
|
|
||||||
case uint16:
|
|
||||||
return float64(ret), nil
|
|
||||||
case int16:
|
|
||||||
return float64(ret), nil
|
|
||||||
case uint32:
|
|
||||||
return float64(ret), nil
|
|
||||||
case int32:
|
|
||||||
return float64(ret), nil
|
|
||||||
case uint64:
|
|
||||||
return float64(ret), nil
|
|
||||||
case int64:
|
|
||||||
return float64(ret), nil
|
|
||||||
case int:
|
|
||||||
return float64(ret), nil
|
|
||||||
case uint:
|
|
||||||
return float64(ret), nil
|
|
||||||
case float32:
|
|
||||||
return float64(ret), nil
|
|
||||||
case float64:
|
|
||||||
return float64(ret), nil
|
|
||||||
case string:
|
|
||||||
floatVal, err := strconv.ParseFloat(ret, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
switch key := keys[0].(type) {
|
|
||||||
case string:
|
|
||||||
nextVal, err := getFromMap(val, key)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
nextKeys := make([]interface{}, len(keys)-1)
|
|
||||||
copy(nextKeys, keys[1:])
|
|
||||||
return getPath(nextVal, nextKeys...)
|
|
||||||
case int:
|
|
||||||
nextVal, err := getFromArray(val, key)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFromMap(val interface{}, key string) (interface{}, error) {
|
|
||||||
mapVal, ok := val.(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("%v is not map[string]interface{}", val)
|
|
||||||
}
|
|
||||||
ret, found := mapVal[key]
|
|
||||||
if !found {
|
|
||||||
return nil, fmt.Errorf("%v not found in %v", key, mapVal)
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFromArray(val interface{}, key int) (interface{}, error) {
|
|
||||||
arrayVal, ok := val.([]interface{})
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("%v is not []interface{}", val)
|
|
||||||
}
|
|
||||||
if key >= len(arrayVal) {
|
|
||||||
return nil, fmt.Errorf("%v exceed %v", key, arrayVal)
|
|
||||||
}
|
|
||||||
if key < 0 {
|
|
||||||
return nil, fmt.Errorf("%v exceed %v", key, arrayVal)
|
|
||||||
}
|
|
||||||
return arrayVal[key], nil
|
|
||||||
}
|
|
@ -2,9 +2,7 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@ -200,108 +198,6 @@ 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) {
|
|
||||||
valueType := iter.WhatIsNext()
|
|
||||||
switch valueType {
|
|
||||||
case String:
|
|
||||||
return MakeAny(iter.ReadString())
|
|
||||||
case Number:
|
|
||||||
return iter.readNumber()
|
|
||||||
case Nil:
|
|
||||||
return MakeAny(nil)
|
|
||||||
case Bool:
|
|
||||||
return MakeAny(iter.ReadBool())
|
|
||||||
case Array:
|
|
||||||
val := []interface{}{}
|
|
||||||
for iter.ReadArray() {
|
|
||||||
element := iter.ReadAny()
|
|
||||||
if iter.Error != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val = append(val, element.val)
|
|
||||||
}
|
|
||||||
return MakeAny(val)
|
|
||||||
case Object:
|
|
||||||
val := map[string]interface{}{}
|
|
||||||
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
|
|
||||||
element := iter.ReadAny()
|
|
||||||
if iter.Error != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val[string([]byte(field))] = element.val
|
|
||||||
}
|
|
||||||
return MakeAny(val)
|
|
||||||
default:
|
|
||||||
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 i := iter.head; i < iter.tail; i++ {
|
|
||||||
c := iter.buf[i]
|
|
||||||
switch c {
|
|
||||||
case '-':
|
|
||||||
foundNegative = true
|
|
||||||
str = append(str, c)
|
|
||||||
continue
|
|
||||||
case '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
|
||||||
str = append(str, c)
|
|
||||||
continue
|
|
||||||
case '.', 'e', 'E':
|
|
||||||
foundFloat = true
|
|
||||||
str = append(str, c)
|
|
||||||
continue
|
|
||||||
default:
|
|
||||||
iter.head = i
|
|
||||||
hasMore = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if !hasMore {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if hasMore {
|
|
||||||
if !iter.loadMore() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
number := *(*string)(unsafe.Pointer(&str))
|
|
||||||
if foundFloat {
|
|
||||||
val, err := strconv.ParseFloat(number, 64)
|
|
||||||
if err != nil {
|
|
||||||
iter.Error = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return MakeAny(val)
|
|
||||||
}
|
|
||||||
if foundNegative {
|
|
||||||
val, err := strconv.ParseInt(number, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
iter.Error = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return MakeAny(val)
|
|
||||||
}
|
|
||||||
val, err := strconv.ParseUint(number, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
iter.Error = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return MakeAny(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read converts an Iterator instance into go interface, same as json.Unmarshal
|
// Read converts an Iterator instance into go interface, same as json.Unmarshal
|
||||||
func (iter *Iterator) ReadVal(obj interface{}) {
|
func (iter *Iterator) ReadVal(obj interface{}) {
|
||||||
typ := reflect.TypeOf(obj)
|
typ := reflect.TypeOf(obj)
|
||||||
@ -365,9 +261,6 @@ func (p prefix) addToEncoder(encoder Encoder, err error) (Encoder, error) {
|
|||||||
|
|
||||||
func decoderOfType(typ reflect.Type) (Decoder, error) {
|
func decoderOfType(typ reflect.Type) (Decoder, error) {
|
||||||
typeName := typ.String()
|
typeName := typ.String()
|
||||||
if typeName == "jsoniter.Any" {
|
|
||||||
return &anyDecoder{}, nil
|
|
||||||
}
|
|
||||||
typeDecoder := typeDecoders[typeName]
|
typeDecoder := typeDecoders[typeName]
|
||||||
if typeDecoder != nil {
|
if typeDecoder != nil {
|
||||||
return typeDecoder, nil
|
return typeDecoder, nil
|
||||||
|
@ -160,20 +160,13 @@ type interfaceCodec struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (codec *interfaceCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
|
func (codec *interfaceCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
*((*interface{})(ptr)) = iter.ReadAny().Get()
|
*((*interface{})(ptr)) = iter.Read()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (codec *interfaceCodec) encode(ptr unsafe.Pointer, stream *Stream) {
|
func (codec *interfaceCodec) encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
stream.WriteVal(*((*interface{})(ptr)))
|
stream.WriteVal(*((*interface{})(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
type anyDecoder struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (decoder *anyDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
||||||
*((*Any)(ptr)) = *iter.ReadAny()
|
|
||||||
}
|
|
||||||
|
|
||||||
type stringNumberDecoder struct {
|
type stringNumberDecoder struct {
|
||||||
elemDecoder Decoder
|
elemDecoder Decoder
|
||||||
}
|
}
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
package jsoniter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_read_string_as_any(t *testing.T) {
|
|
||||||
iter := ParseString(`[1, {"hello": "world"}, 2]`)
|
|
||||||
any := iter.ReadAny()
|
|
||||||
if iter.Error != nil {
|
|
||||||
t.Fatal(iter.Error)
|
|
||||||
}
|
|
||||||
if any.ToString(1, "hello") != "world" {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_read_float64_as_any(t *testing.T) {
|
|
||||||
iter := ParseString(`1.23`)
|
|
||||||
any := iter.ReadAny()
|
|
||||||
if any.ToFloat32() != 1.23 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_read_int_as_any(t *testing.T) {
|
|
||||||
iter := ParseString(`123`)
|
|
||||||
any := iter.ReadAny()
|
|
||||||
if any.ToFloat32() != 123 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_read_any_from_nested(t *testing.T) {
|
|
||||||
iter := ParseString(`{"numbers": ["1", "2", ["3", "4"]]}`)
|
|
||||||
val := iter.ReadAny()
|
|
||||||
if val.ToInt("numbers", 2, 0) != 3 {
|
|
||||||
fmt.Println(val.Error)
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,12 +12,6 @@ func Test_bind_api_demo(t *testing.T) {
|
|||||||
fmt.Println(val[3])
|
fmt.Println(val[3])
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_any_api_demo(t *testing.T) {
|
|
||||||
iter := ParseString(`[0,1,2,3]`)
|
|
||||||
val := iter.ReadAny()
|
|
||||||
fmt.Println(val.Get(3))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_iterator_api_demo(t *testing.T) {
|
func Test_iterator_api_demo(t *testing.T) {
|
||||||
iter := ParseString(`[0,1,2,3]`)
|
iter := ParseString(`[0,1,2,3]`)
|
||||||
total := 0
|
total := 0
|
||||||
@ -27,17 +21,6 @@ func Test_iterator_api_demo(t *testing.T) {
|
|||||||
fmt.Println(total)
|
fmt.Println(total)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ABC struct {
|
|
||||||
a Any
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_deep_nested_any_api(t *testing.T) {
|
|
||||||
iter := ParseString(`{"a": {"b": {"c": "d"}}}`)
|
|
||||||
abc := &ABC{}
|
|
||||||
iter.ReadVal(&abc)
|
|
||||||
fmt.Println(abc.a.Get("b", "c"))
|
|
||||||
}
|
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
userID int
|
userID int
|
||||||
name string
|
name string
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/json-iterator/go/require"
|
"github.com/json-iterator/go/require"
|
||||||
)
|
)
|
||||||
@ -26,16 +24,6 @@ func Test_read_map_of_interface(t *testing.T) {
|
|||||||
should.Equal(map[string]interface{}{"hello": "world"}, iter.Read())
|
should.Equal(map[string]interface{}{"hello": "world"}, iter.Read())
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_read_map_of_any(t *testing.T) {
|
|
||||||
iter := ParseString(`{"hello": "world"}`)
|
|
||||||
m := map[string]Any{"1": *MakeAny("2")}
|
|
||||||
iter.ReadVal(&m)
|
|
||||||
if !reflect.DeepEqual(map[string]Any{"1": *MakeAny("2"), "hello": *MakeAny("world")}, m) {
|
|
||||||
fmt.Println(iter.Error)
|
|
||||||
t.Fatal(m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_write_val_map(t *testing.T) {
|
func Test_write_val_map(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
val := map[string]string{"1": "2"}
|
val := map[string]string{"1": "2"}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user