1
0
mirror of https://github.com/json-iterator/go.git synced 2024-11-30 08:36:43 +02:00
json-iterator/feature_any.go

247 lines
5.1 KiB
Go
Raw Normal View History

2017-01-22 17:29:48 +02:00
package jsoniter
2017-01-28 15:11:36 +02:00
import (
"fmt"
"io"
2017-06-19 17:43:53 +02:00
"reflect"
2017-01-28 15:11:36 +02:00
)
2017-01-26 10:24:01 +02:00
2017-01-22 17:29:48 +02:00
type Any interface {
LastError() error
2017-01-26 10:24:01 +02:00
ValueType() ValueType
2017-06-19 15:21:20 +02:00
MustBeValid() Any
2017-01-22 17:29:48 +02:00
ToBool() bool
ToInt() int
ToInt32() int32
ToInt64() int64
2017-01-29 10:55:32 +02:00
ToUint() uint
ToUint32() uint32
ToUint64() uint64
2017-01-22 17:29:48 +02:00
ToFloat32() float32
ToFloat64() float64
ToString() string
2017-06-19 09:40:00 +02:00
ToVal(val interface{})
Get(path ...interface{}) Any
2017-06-19 09:40:00 +02:00
// TODO: add Set
2017-01-24 16:36:16 +02:00
Size() int
Keys() []string
2017-06-19 09:40:00 +02:00
// TODO: remove me
2017-01-25 16:43:57 +02:00
GetArray() []Any
2017-06-19 09:40:00 +02:00
// TODO: remove me
2017-01-25 16:43:57 +02:00
GetObject() map[string]Any
2017-01-26 09:44:10 +02:00
GetInterface() interface{}
2017-01-25 16:43:57 +02:00
WriteTo(stream *Stream)
}
2017-01-25 16:43:57 +02:00
type baseAny struct{}
2017-01-24 16:56:18 +02:00
func (any *baseAny) Get(path ...interface{}) Any {
2017-01-26 10:24:01 +02:00
return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)}
2017-01-24 16:56:18 +02:00
}
2017-01-24 16:36:16 +02:00
func (any *baseAny) Size() int {
return 0
}
func (any *baseAny) Keys() []string {
return []string{}
}
2017-01-25 16:43:57 +02:00
func (any *baseAny) GetArray() []Any {
return []Any{}
}
func (any *baseAny) GetObject() map[string]Any {
return map[string]Any{}
}
2017-06-19 09:40:00 +02:00
func (any *baseAny) ToVal(obj interface{}) {
panic("not implemented")
}
2017-01-29 10:55:32 +02:00
func WrapInt32(val int32) Any {
return &int32Any{baseAny{}, val}
}
2017-01-25 16:43:57 +02:00
func WrapInt64(val int64) Any {
2017-01-29 10:55:32 +02:00
return &int64Any{baseAny{}, val}
}
func WrapUint32(val uint32) Any {
return &uint32Any{baseAny{}, val}
}
func WrapUint64(val uint64) Any {
return &uint64Any{baseAny{}, val}
2017-01-26 10:33:16 +02:00
}
func WrapFloat64(val float64) Any {
return &floatAny{baseAny{}, val}
2017-01-25 16:43:57 +02:00
}
2017-01-26 10:41:49 +02:00
func WrapString(val string) Any {
return &stringAny{baseAny{}, val}
2017-01-26 10:41:49 +02:00
}
2017-01-28 15:11:36 +02:00
func Wrap(val interface{}) Any {
2017-01-28 17:11:29 +02:00
if val == nil {
return &nilAny{}
}
2017-05-19 13:44:27 +02:00
asAny, isAny := val.(Any)
if isAny {
return asAny
}
2017-01-28 15:11:36 +02:00
type_ := reflect.TypeOf(val)
switch type_.Kind() {
case reflect.Slice:
return wrapArray(val)
2017-01-28 16:45:03 +02:00
case reflect.Struct:
return wrapStruct(val)
2017-01-28 17:11:29 +02:00
case reflect.Map:
return wrapMap(val)
2017-01-28 15:11:36 +02:00
case reflect.String:
return WrapString(val.(string))
case reflect.Int:
return WrapInt64(int64(val.(int)))
case reflect.Int8:
2017-01-29 10:55:32 +02:00
return WrapInt32(int32(val.(int8)))
2017-01-28 15:11:36 +02:00
case reflect.Int16:
2017-01-29 10:55:32 +02:00
return WrapInt32(int32(val.(int16)))
2017-01-28 15:11:36 +02:00
case reflect.Int32:
2017-01-29 10:55:32 +02:00
return WrapInt32(val.(int32))
2017-01-28 15:11:36 +02:00
case reflect.Int64:
return WrapInt64(val.(int64))
case reflect.Uint:
2017-01-29 10:55:32 +02:00
return WrapUint64(uint64(val.(uint)))
2017-01-28 15:11:36 +02:00
case reflect.Uint8:
2017-01-29 10:55:32 +02:00
return WrapUint32(uint32(val.(uint8)))
2017-01-28 15:11:36 +02:00
case reflect.Uint16:
2017-01-29 10:55:32 +02:00
return WrapUint32(uint32(val.(uint16)))
2017-01-28 15:11:36 +02:00
case reflect.Uint32:
2017-01-29 10:55:32 +02:00
return WrapUint32(uint32(val.(uint32)))
2017-01-28 15:11:36 +02:00
case reflect.Uint64:
2017-01-29 10:55:32 +02:00
return WrapUint64(val.(uint64))
2017-01-28 15:11:36 +02:00
case reflect.Float32:
return WrapFloat64(float64(val.(float32)))
case reflect.Float64:
return WrapFloat64(val.(float64))
2017-01-28 17:11:29 +02:00
case reflect.Bool:
if val.(bool) == true {
return &trueAny{}
} else {
return &falseAny{}
}
2017-01-28 15:11:36 +02:00
}
2017-01-28 17:11:29 +02:00
return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", type_)}
2017-01-28 15:11:36 +02:00
}
2017-01-22 17:29:48 +02:00
func (iter *Iterator) ReadAny() Any {
2017-06-17 15:10:08 +02:00
return iter.readAny()
}
2017-06-17 15:10:08 +02:00
func (iter *Iterator) readAny() Any {
2017-01-23 02:45:57 +02:00
c := iter.nextToken()
switch c {
case '"':
iter.unreadByte()
return &stringAny{baseAny{}, iter.ReadString()}
2017-01-23 02:45:57 +02:00
case 'n':
iter.skipFixedBytes(3) // null
2017-01-22 17:29:48 +02:00
return &nilAny{}
2017-01-23 02:45:57 +02:00
case 't':
iter.skipFixedBytes(3) // true
return &trueAny{}
case 'f':
iter.skipFixedBytes(4) // false
return &falseAny{}
case '{':
2017-06-17 15:10:08 +02:00
return iter.readObjectAny()
2017-01-24 16:36:16 +02:00
case '[':
2017-06-17 15:10:08 +02:00
return iter.readArrayAny()
2017-06-18 11:00:28 +02:00
case '-':
return iter.readNumberAny(false)
2017-01-24 16:36:16 +02:00
default:
2017-06-18 11:00:28 +02:00
return iter.readNumberAny(true)
2017-01-22 17:29:48 +02:00
}
}
2017-06-18 11:00:28 +02:00
func (iter *Iterator) readNumberAny(positive bool) Any {
iter.startCapture(iter.head - 1)
iter.skipNumber()
2017-06-18 11:00:28 +02:00
lazyBuf := iter.stopCapture()
return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
2017-01-23 02:33:43 +02:00
}
2017-06-17 15:10:08 +02:00
func (iter *Iterator) readObjectAny() Any {
2017-06-18 11:00:28 +02:00
iter.startCapture(iter.head - 1)
iter.skipObject()
lazyBuf := iter.stopCapture()
return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
2017-01-22 17:29:48 +02:00
}
2017-01-24 16:36:16 +02:00
2017-06-17 15:10:08 +02:00
func (iter *Iterator) readArrayAny() Any {
2017-06-18 11:00:28 +02:00
iter.startCapture(iter.head - 1)
iter.skipArray()
lazyBuf := iter.stopCapture()
return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
2017-01-24 16:36:16 +02:00
}
func locateObjectField(iter *Iterator, target string) []byte {
var found []byte
iter.ReadObjectCB(func(iter *Iterator, field string) bool {
if field == target {
found = iter.SkipAndReturnBytes()
return false
}
iter.Skip()
return true
})
return found
}
func locateArrayElement(iter *Iterator, target int) []byte {
var found []byte
n := 0
iter.ReadArrayCB(func(iter *Iterator) bool {
if n == target {
found = iter.SkipAndReturnBytes()
return false
}
iter.Skip()
n++
return true
})
return found
}
func locatePath(iter *Iterator, path []interface{}) Any {
for i, pathKeyObj := range path {
switch pathKey := pathKeyObj.(type) {
case string:
valueBytes := locateObjectField(iter, pathKey)
2017-06-19 15:21:20 +02:00
if valueBytes == nil {
return newInvalidAny(path[i:])
}
iter.ResetBytes(valueBytes)
case int:
valueBytes := locateArrayElement(iter, pathKey)
2017-06-19 15:21:20 +02:00
if valueBytes == nil {
return newInvalidAny(path[i:])
}
iter.ResetBytes(valueBytes)
case int32:
if '*' == pathKey {
return iter.readAny().Get(path[i:]...)
} else {
2017-06-19 15:21:20 +02:00
return newInvalidAny(path[i:])
}
default:
return newInvalidAny(path[i:])
}
}
if iter.Error != nil && iter.Error != io.EOF {
return &invalidAny{baseAny{}, iter.Error}
}
return iter.readAny()
2017-06-19 15:21:20 +02:00
}