1
0
mirror of https://github.com/json-iterator/go.git synced 2025-03-23 21:09:11 +02:00
json-iterator/feature_any.go

305 lines
7.0 KiB
Go
Raw Normal View History

2017-01-22 23:29:48 +08:00
package jsoniter
2017-01-28 21:11:36 +08:00
import (
"fmt"
"reflect"
)
2017-01-26 16:24:01 +08:00
2017-01-22 23:29:48 +08:00
type Any interface {
LastError() error
2017-01-26 16:24:01 +08:00
ValueType() ValueType
2017-01-22 23:29:48 +08:00
ToBool() bool
ToInt() int
ToInt32() int32
ToInt64() int64
2017-01-29 16:55:32 +08:00
ToUint() uint
ToUint32() uint32
ToUint64() uint64
2017-01-22 23:29:48 +08:00
ToFloat32() float32
ToFloat64() float64
ToString() string
Get(path ...interface{}) Any
2017-01-24 22:36:16 +08:00
Size() int
Keys() []string
IterateObject() (func() (string, Any, bool), bool)
2017-01-24 22:47:56 +08:00
IterateArray() (func() (Any, bool), bool)
2017-01-25 22:43:57 +08:00
GetArray() []Any
SetArray(newList []Any) bool
GetObject() map[string]Any
SetObject(map[string]Any) bool
2017-01-26 15:44:10 +08:00
GetInterface() interface{}
2017-01-25 22:43:57 +08:00
WriteTo(stream *Stream)
2017-01-26 15:40:38 +08:00
Parse() *Iterator
}
2017-01-25 22:43:57 +08:00
type baseAny struct{}
2017-01-24 22:56:18 +08:00
func (any *baseAny) Get(path ...interface{}) Any {
2017-01-26 16:24:01 +08:00
return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)}
2017-01-24 22:56:18 +08:00
}
2017-01-24 22:36:16 +08:00
func (any *baseAny) Size() int {
return 0
}
func (any *baseAny) Keys() []string {
return []string{}
}
func (any *baseAny) IterateObject() (func() (string, Any, bool), bool) {
return nil, false
2017-01-22 23:29:48 +08:00
}
2017-01-24 22:47:56 +08:00
func (any *baseAny) IterateArray() (func() (Any, bool), bool) {
return nil, false
}
2017-01-25 22:43:57 +08:00
func (any *baseAny) GetArray() []Any {
return []Any{}
}
func (any *baseAny) SetArray(newList []Any) bool {
return false
}
func (any *baseAny) GetObject() map[string]Any {
return map[string]Any{}
}
func (any *baseAny) SetObject(map[string]Any) bool {
return false
}
2017-01-29 16:55:32 +08:00
func WrapInt32(val int32) Any {
return &int32Any{baseAny{}, val}
}
2017-01-25 22:43:57 +08:00
func WrapInt64(val int64) Any {
2017-01-29 16:55:32 +08: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 16:33:16 +08:00
}
func WrapFloat64(val float64) Any {
return &floatAny{baseAny{}, val}
2017-01-25 22:43:57 +08:00
}
2017-01-26 16:41:49 +08:00
func WrapString(val string) Any {
return &stringAny{baseAny{}, nil, val}
}
2017-01-28 21:11:36 +08:00
func Wrap(val interface{}) Any {
2017-01-28 23:11:29 +08:00
if val == nil {
return &nilAny{}
}
2017-05-19 19:44:27 +08:00
asAny, isAny := val.(Any)
if isAny {
return asAny
}
2017-01-28 21:11:36 +08:00
type_ := reflect.TypeOf(val)
switch type_.Kind() {
case reflect.Slice:
return wrapArray(val)
2017-01-28 22:45:03 +08:00
case reflect.Struct:
return wrapStruct(val)
2017-01-28 23:11:29 +08:00
case reflect.Map:
return wrapMap(val)
2017-01-28 21:11:36 +08:00
case reflect.String:
return WrapString(val.(string))
case reflect.Int:
return WrapInt64(int64(val.(int)))
case reflect.Int8:
2017-01-29 16:55:32 +08:00
return WrapInt32(int32(val.(int8)))
2017-01-28 21:11:36 +08:00
case reflect.Int16:
2017-01-29 16:55:32 +08:00
return WrapInt32(int32(val.(int16)))
2017-01-28 21:11:36 +08:00
case reflect.Int32:
2017-01-29 16:55:32 +08:00
return WrapInt32(val.(int32))
2017-01-28 21:11:36 +08:00
case reflect.Int64:
return WrapInt64(val.(int64))
case reflect.Uint:
2017-01-29 16:55:32 +08:00
return WrapUint64(uint64(val.(uint)))
2017-01-28 21:11:36 +08:00
case reflect.Uint8:
2017-01-29 16:55:32 +08:00
return WrapUint32(uint32(val.(uint8)))
2017-01-28 21:11:36 +08:00
case reflect.Uint16:
2017-01-29 16:55:32 +08:00
return WrapUint32(uint32(val.(uint16)))
2017-01-28 21:11:36 +08:00
case reflect.Uint32:
2017-01-29 16:55:32 +08:00
return WrapUint32(uint32(val.(uint32)))
2017-01-28 21:11:36 +08:00
case reflect.Uint64:
2017-01-29 16:55:32 +08:00
return WrapUint64(val.(uint64))
2017-01-28 21:11:36 +08:00
case reflect.Float32:
return WrapFloat64(float64(val.(float32)))
case reflect.Float64:
return WrapFloat64(val.(float64))
2017-01-28 23:11:29 +08:00
case reflect.Bool:
if val.(bool) == true {
return &trueAny{}
} else {
return &falseAny{}
}
2017-01-28 21:11:36 +08:00
}
2017-01-28 23:11:29 +08:00
return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", type_)}
2017-01-28 21:11:36 +08:00
}
2017-01-22 23:29:48 +08:00
func (iter *Iterator) ReadAny() Any {
return iter.readAny(nil)
}
func (iter *Iterator) readAny(reusableIter *Iterator) Any {
2017-01-23 08:45:57 +08:00
c := iter.nextToken()
switch c {
case '"':
return iter.readStringAny(reusableIter)
2017-01-23 08:45:57 +08:00
case 'n':
iter.skipFixedBytes(3) // null
2017-01-22 23:29:48 +08:00
return &nilAny{}
2017-01-23 08:45:57 +08:00
case 't':
iter.skipFixedBytes(3) // true
return &trueAny{}
case 'f':
iter.skipFixedBytes(4) // false
return &falseAny{}
case '{':
return iter.readObjectAny(reusableIter)
2017-01-24 22:36:16 +08:00
case '[':
return iter.readArrayAny(reusableIter)
default:
2017-01-29 16:55:32 +08:00
return iter.readNumberAny(reusableIter, c)
2017-01-22 23:29:48 +08:00
}
}
2017-01-29 16:55:32 +08:00
func (iter *Iterator) readNumberAny(reusableIter *Iterator, firstByte byte) Any {
2017-01-22 23:29:48 +08:00
dotFound := false
2017-01-29 16:55:32 +08:00
lazyBuf := make([]byte, 1, 8)
lazyBuf[0] = firstByte
2017-01-22 23:29:48 +08:00
for {
for i := iter.head; i < iter.tail; i++ {
c := iter.buf[i]
if c == '.' {
dotFound = true
continue
}
switch c {
case ' ', '\n', '\r', '\t', ',', '}', ']':
lazyBuf = append(lazyBuf, iter.buf[iter.head:i]...)
iter.head = i
2017-01-23 08:33:43 +08:00
if dotFound {
2017-01-29 16:55:32 +08:00
return &float64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
2017-01-23 08:33:43 +08:00
} else {
2017-01-29 16:55:32 +08:00
if firstByte == '-' {
return &int64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
} else {
return &uint64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
}
2017-01-23 08:33:43 +08:00
}
2017-01-22 23:29:48 +08:00
}
}
lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
if !iter.loadMore() {
2017-01-23 08:33:43 +08:00
iter.head = iter.tail
if dotFound {
2017-01-29 16:55:32 +08:00
return &float64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
2017-01-23 08:33:43 +08:00
} else {
2017-01-29 16:55:32 +08:00
if firstByte == '-' {
return &int64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
} else {
return &uint64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
}
2017-01-23 08:33:43 +08:00
}
}
}
}
func (iter *Iterator) readStringAny(reusableIter *Iterator) Any {
2017-01-23 08:33:43 +08:00
lazyBuf := make([]byte, 1, 8)
lazyBuf[0] = '"'
for {
end, escaped := iter.findStringEnd()
if end == -1 {
lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
if !iter.loadMore() {
iter.reportError("readStringAny", "incomplete string")
return &invalidAny{}
}
if escaped {
iter.head = 1 // skip the first char as last char read is \
}
} else {
lazyBuf = append(lazyBuf, iter.buf[iter.head:end]...)
iter.head = end
return &stringLazyAny{baseAny{}, lazyBuf, reusableIter, nil, ""}
}
}
}
func (iter *Iterator) readObjectAny(reusableIter *Iterator) Any {
level := 1
lazyBuf := make([]byte, 1, 32)
lazyBuf[0] = '{'
for {
start := iter.head
for i := iter.head; i < iter.tail; i++ {
switch iter.buf[i] {
case '"': // If inside string, skip it
iter.head = i + 1
iter.skipString()
i = iter.head - 1 // it will be i++ soon
case '{': // If open symbol, increase level
level++
case '}': // If close symbol, increase level
level--
// If we have returned to the original level, we're done
if level == 0 {
iter.head = i + 1
lazyBuf = append(lazyBuf, iter.buf[start:iter.head]...)
2017-01-24 22:36:16 +08:00
return &objectLazyAny{baseAny{}, lazyBuf, reusableIter, nil, nil, lazyBuf}
}
}
}
lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
if !iter.loadMore() {
iter.reportError("skipObject", "incomplete object")
return &invalidAny{}
2017-01-22 23:29:48 +08:00
}
}
}
2017-01-24 22:36:16 +08:00
func (iter *Iterator) readArrayAny(reusableIter *Iterator) Any {
level := 1
lazyBuf := make([]byte, 1, 32)
2017-01-26 00:25:17 +08:00
lazyBuf[0] = '['
2017-01-24 22:36:16 +08:00
for {
start := iter.head
for i := iter.head; i < iter.tail; i++ {
switch iter.buf[i] {
case '"': // If inside string, skip it
iter.head = i + 1
iter.skipString()
i = iter.head - 1 // it will be i++ soon
case '[': // If open symbol, increase level
level++
case ']': // If close symbol, increase level
level--
// If we have returned to the original level, we're done
if level == 0 {
iter.head = i + 1
lazyBuf = append(lazyBuf, iter.buf[start:iter.head]...)
2017-01-25 22:43:57 +08:00
return &arrayLazyAny{baseAny{}, lazyBuf, reusableIter, nil, nil, lazyBuf}
2017-01-24 22:36:16 +08:00
}
}
}
lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
if !iter.loadMore() {
iter.reportError("skipArray", "incomplete array")
return &invalidAny{}
}
}
}