Tao Wen 8 роки тому
батько
коміт
9df37bbd68
7 змінених файлів з 1 додано та 703 видалено
  1. 0 72
      any_test.go
  2. 0 445
      feature_any.go
  3. 0 107
      feature_reflect.go
  4. 1 8
      feature_reflect_native.go
  5. 0 42
      jsoniter_any_test.go
  6. 0 17
      jsoniter_demo_test.go
  7. 0 12
      jsoniter_map_test.go

+ 0 - 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()
-	}
-}

+ 0 - 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
-}

+ 0 - 107
feature_reflect.go

@@ -2,9 +2,7 @@ package jsoniter
 
 import (
 	"fmt"
-	"io"
 	"reflect"
-	"strconv"
 	"sync/atomic"
 	"unsafe"
 )
@@ -200,108 +198,6 @@ 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 {
-	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
 func (iter *Iterator) ReadVal(obj interface{}) {
 	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) {
 	typeName := typ.String()
-	if typeName == "jsoniter.Any" {
-		return &anyDecoder{}, nil
-	}
 	typeDecoder := typeDecoders[typeName]
 	if typeDecoder != nil {
 		return typeDecoder, nil

+ 1 - 8
feature_reflect_native.go

@@ -160,20 +160,13 @@ type interfaceCodec struct {
 }
 
 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) {
 	stream.WriteVal(*((*interface{})(ptr)))
 }
 
-type anyDecoder struct {
-}
-
-func (decoder *anyDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
-	*((*Any)(ptr)) = *iter.ReadAny()
-}
-
 type stringNumberDecoder struct {
 	elemDecoder Decoder
 }

+ 0 - 42
jsoniter_any_test.go

@@ -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()
-	}
-}

+ 0 - 17
jsoniter_demo_test.go

@@ -12,12 +12,6 @@ func Test_bind_api_demo(t *testing.T) {
 	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) {
 	iter := ParseString(`[0,1,2,3]`)
 	total := 0
@@ -27,17 +21,6 @@ func Test_iterator_api_demo(t *testing.T) {
 	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 {
 	userID int
 	name   string

+ 0 - 12
jsoniter_map_test.go

@@ -1,8 +1,6 @@
 package jsoniter
 
 import (
-	"fmt"
-	"reflect"
 	"testing"
 	"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())
 }
 
-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) {
 	should := require.New(t)
 	val := map[string]string{"1": "2"}