mirror of
https://github.com/json-iterator/go.git
synced 2025-03-26 21:12:40 +02:00
make any easier to work with
This commit is contained in:
parent
e427475e9c
commit
2895fe2215
148
any.go
148
any.go
@ -3,15 +3,20 @@ package jsoniter
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Any struct {
|
type Any struct {
|
||||||
Val interface{}
|
val interface{}
|
||||||
Error error
|
Error error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetObject(keys ...interface{}) interface{} {
|
func any(val interface{}) Any {
|
||||||
ret, err := getPath(any.Val, keys...)
|
return Any{val, nil}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *Any) Get(keys ...interface{}) interface{} {
|
||||||
|
ret, err := getPath(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return "";
|
return "";
|
||||||
@ -19,22 +24,91 @@ func (any *Any) GetObject(keys ...interface{}) interface{} {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetString(keys ...interface{}) string {
|
func (any *Any) GetValueType(keys ...interface{}) ValueType {
|
||||||
ret, err := getPath(any.Val, keys...)
|
ret, err := getPath(any.val, keys...)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *Any) ToString(keys ...interface{}) string {
|
||||||
|
ret, err := getPath(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
typedRet, ok := ret.(string)
|
switch ret := ret.(type) {
|
||||||
if !ok {
|
case uint8:
|
||||||
any.Error = fmt.Errorf("%v is not string", ret);
|
return strconv.FormatInt(int64(ret), 10);
|
||||||
return "";
|
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)
|
||||||
}
|
}
|
||||||
return typedRet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetUint8(keys ...interface{}) uint8 {
|
func (any *Any) ToUint8(keys ...interface{}) uint8 {
|
||||||
ret, err := getPathAsInt64(any.Val, keys...)
|
ret, err := getPathAsInt64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -42,8 +116,8 @@ func (any *Any) GetUint8(keys ...interface{}) uint8 {
|
|||||||
return uint8(ret)
|
return uint8(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetInt8(keys ...interface{}) int8 {
|
func (any *Any) ToInt8(keys ...interface{}) int8 {
|
||||||
ret, err := getPathAsInt64(any.Val, keys...)
|
ret, err := getPathAsInt64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -51,8 +125,8 @@ func (any *Any) GetInt8(keys ...interface{}) int8 {
|
|||||||
return int8(ret)
|
return int8(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetUint16(keys ...interface{}) uint16 {
|
func (any *Any) ToUint16(keys ...interface{}) uint16 {
|
||||||
ret, err := getPathAsInt64(any.Val, keys...)
|
ret, err := getPathAsInt64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -60,8 +134,8 @@ func (any *Any) GetUint16(keys ...interface{}) uint16 {
|
|||||||
return uint16(ret)
|
return uint16(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetInt16(keys ...interface{}) int16 {
|
func (any *Any) ToInt16(keys ...interface{}) int16 {
|
||||||
ret, err := getPathAsInt64(any.Val, keys...)
|
ret, err := getPathAsInt64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -69,8 +143,8 @@ func (any *Any) GetInt16(keys ...interface{}) int16 {
|
|||||||
return int16(ret)
|
return int16(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetUint32(keys ...interface{}) uint32 {
|
func (any *Any) ToUint32(keys ...interface{}) uint32 {
|
||||||
ret, err := getPathAsInt64(any.Val, keys...)
|
ret, err := getPathAsInt64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -78,8 +152,8 @@ func (any *Any) GetUint32(keys ...interface{}) uint32 {
|
|||||||
return uint32(ret)
|
return uint32(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetInt32(keys ...interface{}) int32 {
|
func (any *Any) ToInt32(keys ...interface{}) int32 {
|
||||||
ret, err := getPathAsInt64(any.Val, keys...)
|
ret, err := getPathAsInt64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -87,8 +161,8 @@ func (any *Any) GetInt32(keys ...interface{}) int32 {
|
|||||||
return int32(ret)
|
return int32(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetUint64(keys ...interface{}) uint64 {
|
func (any *Any) ToUint64(keys ...interface{}) uint64 {
|
||||||
ret, err := getPathAsUint64(any.Val, keys...)
|
ret, err := getPathAsUint64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -96,8 +170,8 @@ func (any *Any) GetUint64(keys ...interface{}) uint64 {
|
|||||||
return uint64(ret)
|
return uint64(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetInt64(keys ...interface{}) int64 {
|
func (any *Any) ToInt64(keys ...interface{}) int64 {
|
||||||
ret, err := getPathAsInt64(any.Val, keys...)
|
ret, err := getPathAsInt64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -105,8 +179,8 @@ func (any *Any) GetInt64(keys ...interface{}) int64 {
|
|||||||
return int64(ret)
|
return int64(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetInt(keys ...interface{}) int {
|
func (any *Any) ToInt(keys ...interface{}) int {
|
||||||
ret, err := getPathAsInt64(any.Val, keys...)
|
ret, err := getPathAsInt64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -114,8 +188,8 @@ func (any *Any) GetInt(keys ...interface{}) int {
|
|||||||
return int(ret)
|
return int(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetUint(keys ...interface{}) uint {
|
func (any *Any) ToUint(keys ...interface{}) uint {
|
||||||
ret, err := getPathAsInt64(any.Val, keys...)
|
ret, err := getPathAsInt64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -123,8 +197,8 @@ func (any *Any) GetUint(keys ...interface{}) uint {
|
|||||||
return uint(ret)
|
return uint(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetFloat32(keys ...interface{}) float32 {
|
func (any *Any) ToFloat32(keys ...interface{}) float32 {
|
||||||
ret, err := getPathAsFloat64(any.Val, keys...)
|
ret, err := getPathAsFloat64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -132,8 +206,8 @@ func (any *Any) GetFloat32(keys ...interface{}) float32 {
|
|||||||
return float32(ret)
|
return float32(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetFloat64(keys ...interface{}) float64 {
|
func (any *Any) ToFloat64(keys ...interface{}) float64 {
|
||||||
ret, err := getPathAsFloat64(any.Val, keys...)
|
ret, err := getPathAsFloat64(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return 0;
|
return 0;
|
||||||
@ -141,8 +215,8 @@ func (any *Any) GetFloat64(keys ...interface{}) float64 {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) GetBool(keys ...interface{}) bool {
|
func (any *Any) ToBool(keys ...interface{}) bool {
|
||||||
ret, err := getPath(any.Val, keys...)
|
ret, err := getPath(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return false;
|
return false;
|
||||||
@ -156,7 +230,7 @@ func (any *Any) GetBool(keys ...interface{}) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (any *Any) IsNull(keys ...interface{}) bool {
|
func (any *Any) IsNull(keys ...interface{}) bool {
|
||||||
ret, err := getPath(any.Val, keys...)
|
ret, err := getPath(any.val, keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
any.Error = err
|
any.Error = err
|
||||||
return false;
|
return false;
|
||||||
|
31
any_test.go
31
any_test.go
@ -6,34 +6,34 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Test_get_from_map(t *testing.T) {
|
func Test_get_from_map(t *testing.T) {
|
||||||
any := Any{Val: map[string]interface{}{
|
any := Any{val: map[string]interface{}{
|
||||||
"hello": "world",
|
"hello": "world",
|
||||||
}}
|
}}
|
||||||
if any.GetString("hello") != "world" {
|
if any.ToString("hello") != "world" {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_get_from_array(t *testing.T) {
|
func Test_get_from_array(t *testing.T) {
|
||||||
any := Any{Val: []interface{}{
|
any := Any{val: []interface{}{
|
||||||
"hello", "world",
|
"hello", "world",
|
||||||
}}
|
}}
|
||||||
if any.GetString(1) != "world" {
|
if any.ToString(1) != "world" {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_get_int(t *testing.T) {
|
func Test_get_int(t *testing.T) {
|
||||||
any := Any{Val: []interface{}{
|
any := Any{val: []interface{}{
|
||||||
1, 2, 3,
|
1, 2, 3,
|
||||||
}}
|
}}
|
||||||
if any.GetInt(1) != 2 {
|
if any.ToInt(1) != 2 {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_is_null(t *testing.T) {
|
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.IsNull() != false {
|
||||||
@ -42,22 +42,31 @@ func Test_is_null(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_get_bool(t *testing.T) {
|
func Test_get_bool(t *testing.T) {
|
||||||
any := Any{Val: []interface{}{
|
any := Any{val: []interface{}{
|
||||||
true, true, false,
|
true, true, false,
|
||||||
}}
|
}}
|
||||||
if any.GetBool(1) != true {
|
if any.ToBool(1) != true {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_nested_read(t *testing.T) {
|
func Test_nested_read(t *testing.T) {
|
||||||
any := Any{Val: []interface{}{
|
any := Any{val: []interface{}{
|
||||||
true, map[string]interface{}{
|
true, map[string]interface{}{
|
||||||
"hello": "world",
|
"hello": "world",
|
||||||
}, false,
|
}, false,
|
||||||
}}
|
}}
|
||||||
if any.GetString(1, "hello") != "world" {
|
if any.ToString(1, "hello") != "world" {
|
||||||
fmt.Println(any.Error)
|
fmt.Println(any.Error)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_int_to_string(t *testing.T) {
|
||||||
|
any := Any{val: []interface{}{
|
||||||
|
true, 5, false,
|
||||||
|
}}
|
||||||
|
if any.ToString(1) != "5" {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,7 +16,7 @@ const (
|
|||||||
String
|
String
|
||||||
Number
|
Number
|
||||||
Null
|
Null
|
||||||
Boolean
|
Bool
|
||||||
Array
|
Array
|
||||||
Object
|
Object
|
||||||
)
|
)
|
||||||
@ -54,8 +54,8 @@ func init() {
|
|||||||
valueTypes['7'] = Number;
|
valueTypes['7'] = Number;
|
||||||
valueTypes['8'] = Number;
|
valueTypes['8'] = Number;
|
||||||
valueTypes['9'] = Number;
|
valueTypes['9'] = Number;
|
||||||
valueTypes['t'] = Boolean;
|
valueTypes['t'] = Bool;
|
||||||
valueTypes['f'] = Boolean;
|
valueTypes['f'] = Bool;
|
||||||
valueTypes['n'] = Null;
|
valueTypes['n'] = Null;
|
||||||
valueTypes['['] = Array;
|
valueTypes['['] = Array;
|
||||||
valueTypes['{'] = Object;
|
valueTypes['{'] = Object;
|
||||||
|
@ -5,7 +5,7 @@ import "testing"
|
|||||||
func Test_read_string_as_any(t *testing.T) {
|
func Test_read_string_as_any(t *testing.T) {
|
||||||
iter := ParseString(`[1, {"hello": "world"}, 2]`)
|
iter := ParseString(`[1, {"hello": "world"}, 2]`)
|
||||||
any := iter.ReadAny()
|
any := iter.ReadAny()
|
||||||
if any.GetString(1, "hello") != "world" {
|
if any.ToString(1, "hello") != "world" {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,7 +13,7 @@ func Test_read_string_as_any(t *testing.T) {
|
|||||||
func Test_read_float64_as_any(t *testing.T) {
|
func Test_read_float64_as_any(t *testing.T) {
|
||||||
iter := ParseString(`1.23`)
|
iter := ParseString(`1.23`)
|
||||||
any := iter.ReadAny()
|
any := iter.ReadAny()
|
||||||
if any.GetFloat32() != 1.23 {
|
if any.ToFloat32() != 1.23 {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21,7 +21,7 @@ func Test_read_float64_as_any(t *testing.T) {
|
|||||||
func Test_read_int_as_any(t *testing.T) {
|
func Test_read_int_as_any(t *testing.T) {
|
||||||
iter := ParseString(`123`)
|
iter := ParseString(`123`)
|
||||||
any := iter.ReadAny()
|
any := iter.ReadAny()
|
||||||
if any.GetFloat32() != 123 {
|
if any.ToFloat32() != 123 {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,3 +15,23 @@ func Test_read_map(t *testing.T) {
|
|||||||
t.Fatal(m)
|
t.Fatal(m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_read_map_of_interface(t *testing.T) {
|
||||||
|
iter := ParseString(`{"hello": "world"}`)
|
||||||
|
m := map[string]interface{}{"1": "2"}
|
||||||
|
iter.Read(&m)
|
||||||
|
if !reflect.DeepEqual(map[string]interface{}{"1": "2", "hello": "world"}, m) {
|
||||||
|
fmt.Println(iter.Error)
|
||||||
|
t.Fatal(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_read_map_of_any(t *testing.T) {
|
||||||
|
iter := ParseString(`{"hello": "world"}`)
|
||||||
|
m := map[string]Any{"1": any("2")}
|
||||||
|
iter.Read(&m)
|
||||||
|
if !reflect.DeepEqual(map[string]Any{"1": any("2"), "hello": any("world")}, m) {
|
||||||
|
fmt.Println(iter.Error)
|
||||||
|
t.Fatal(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -113,6 +113,21 @@ func (decoder *boolDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|||||||
*((*bool)(ptr)) = iter.ReadBool()
|
*((*bool)(ptr)) = iter.ReadBool()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type interfaceDecoder struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (decoder *interfaceDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
*((*interface{})(ptr)) = iter.ReadAny().Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
@ -413,12 +428,12 @@ func reuseSlice(slice *sliceHeader, sliceType reflect.Type, expectedCap int) {
|
|||||||
|
|
||||||
var DECODERS unsafe.Pointer
|
var DECODERS unsafe.Pointer
|
||||||
|
|
||||||
func addDecoderToCache(cacheKey string, decoder Decoder) {
|
func addDecoderToCache(cacheKey reflect.Type, decoder Decoder) {
|
||||||
retry := true
|
retry := true
|
||||||
for retry {
|
for retry {
|
||||||
ptr := atomic.LoadPointer(&DECODERS)
|
ptr := atomic.LoadPointer(&DECODERS)
|
||||||
cache := *(*map[string]Decoder)(ptr)
|
cache := *(*map[reflect.Type]Decoder)(ptr)
|
||||||
copy := map[string]Decoder{}
|
copy := map[reflect.Type]Decoder{}
|
||||||
for k, v := range cache {
|
for k, v := range cache {
|
||||||
copy[k] = v
|
copy[k] = v
|
||||||
}
|
}
|
||||||
@ -427,9 +442,9 @@ func addDecoderToCache(cacheKey string, decoder Decoder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDecoderFromCache(cacheKey string) Decoder {
|
func getDecoderFromCache(cacheKey reflect.Type) Decoder {
|
||||||
ptr := atomic.LoadPointer(&DECODERS)
|
ptr := atomic.LoadPointer(&DECODERS)
|
||||||
cache := *(*map[string]Decoder)(ptr)
|
cache := *(*map[reflect.Type]Decoder)(ptr)
|
||||||
return cache[cacheKey]
|
return cache[cacheKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,7 +517,7 @@ func (iter *Iterator) ReadAny() (ret *Any) {
|
|||||||
return &Any{val, nil}
|
return &Any{val, nil}
|
||||||
case Null:
|
case Null:
|
||||||
return &Any{nil, nil}
|
return &Any{nil, nil}
|
||||||
case Boolean:
|
case Bool:
|
||||||
return &Any{iter.ReadBool(), nil}
|
return &Any{iter.ReadBool(), nil}
|
||||||
case Array:
|
case Array:
|
||||||
val := []interface{}{}
|
val := []interface{}{}
|
||||||
@ -511,7 +526,7 @@ func (iter *Iterator) ReadAny() (ret *Any) {
|
|||||||
if iter.Error != nil {
|
if iter.Error != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val = append(val, element.Val)
|
val = append(val, element.val)
|
||||||
}
|
}
|
||||||
return &Any{val, nil}
|
return &Any{val, nil}
|
||||||
case Object:
|
case Object:
|
||||||
@ -521,7 +536,7 @@ func (iter *Iterator) ReadAny() (ret *Any) {
|
|||||||
if iter.Error != nil {
|
if iter.Error != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val[field] = element.Val
|
val[field] = element.val
|
||||||
}
|
}
|
||||||
return &Any{val, nil}
|
return &Any{val, nil}
|
||||||
default:
|
default:
|
||||||
@ -532,7 +547,7 @@ func (iter *Iterator) ReadAny() (ret *Any) {
|
|||||||
|
|
||||||
func (iter *Iterator) Read(obj interface{}) {
|
func (iter *Iterator) Read(obj interface{}) {
|
||||||
type_ := reflect.TypeOf(obj)
|
type_ := reflect.TypeOf(obj)
|
||||||
cacheKey := type_.String()
|
cacheKey := type_.Elem()
|
||||||
cachedDecoder := getDecoderFromCache(cacheKey)
|
cachedDecoder := getDecoderFromCache(cacheKey)
|
||||||
if cachedDecoder == nil {
|
if cachedDecoder == nil {
|
||||||
decoder, err := decoderOfType(type_)
|
decoder, err := decoderOfType(type_)
|
||||||
@ -566,7 +581,11 @@ func decoderOfType(type_ reflect.Type) (Decoder, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
|
func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
|
||||||
typeDecoder := typeDecoders[type_.String()]
|
typeName := type_.String()
|
||||||
|
if typeName == "jsoniter.Any" {
|
||||||
|
return &anyDecoder{}, nil
|
||||||
|
}
|
||||||
|
typeDecoder := typeDecoders[typeName]
|
||||||
if typeDecoder != nil {
|
if typeDecoder != nil {
|
||||||
return typeDecoder, nil
|
return typeDecoder, nil
|
||||||
}
|
}
|
||||||
@ -599,6 +618,8 @@ func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
|
|||||||
return &float64Decoder{}, nil
|
return &float64Decoder{}, nil
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
return &boolDecoder{}, nil
|
return &boolDecoder{}, nil
|
||||||
|
case reflect.Interface:
|
||||||
|
return &interfaceDecoder{}, nil
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
return decoderOfStruct(type_)
|
return decoderOfStruct(type_)
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user