gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

any.go (7195B)


      1 package jsoniter
      2 
      3 import (
      4 	"errors"
      5 	"fmt"
      6 	"github.com/modern-go/reflect2"
      7 	"io"
      8 	"reflect"
      9 	"strconv"
     10 	"unsafe"
     11 )
     12 
     13 // Any generic object representation.
     14 // The lazy json implementation holds []byte and parse lazily.
     15 type Any interface {
     16 	LastError() error
     17 	ValueType() ValueType
     18 	MustBeValid() Any
     19 	ToBool() bool
     20 	ToInt() int
     21 	ToInt32() int32
     22 	ToInt64() int64
     23 	ToUint() uint
     24 	ToUint32() uint32
     25 	ToUint64() uint64
     26 	ToFloat32() float32
     27 	ToFloat64() float64
     28 	ToString() string
     29 	ToVal(val interface{})
     30 	Get(path ...interface{}) Any
     31 	Size() int
     32 	Keys() []string
     33 	GetInterface() interface{}
     34 	WriteTo(stream *Stream)
     35 }
     36 
     37 type baseAny struct{}
     38 
     39 func (any *baseAny) Get(path ...interface{}) Any {
     40 	return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
     41 }
     42 
     43 func (any *baseAny) Size() int {
     44 	return 0
     45 }
     46 
     47 func (any *baseAny) Keys() []string {
     48 	return []string{}
     49 }
     50 
     51 func (any *baseAny) ToVal(obj interface{}) {
     52 	panic("not implemented")
     53 }
     54 
     55 // WrapInt32 turn int32 into Any interface
     56 func WrapInt32(val int32) Any {
     57 	return &int32Any{baseAny{}, val}
     58 }
     59 
     60 // WrapInt64 turn int64 into Any interface
     61 func WrapInt64(val int64) Any {
     62 	return &int64Any{baseAny{}, val}
     63 }
     64 
     65 // WrapUint32 turn uint32 into Any interface
     66 func WrapUint32(val uint32) Any {
     67 	return &uint32Any{baseAny{}, val}
     68 }
     69 
     70 // WrapUint64 turn uint64 into Any interface
     71 func WrapUint64(val uint64) Any {
     72 	return &uint64Any{baseAny{}, val}
     73 }
     74 
     75 // WrapFloat64 turn float64 into Any interface
     76 func WrapFloat64(val float64) Any {
     77 	return &floatAny{baseAny{}, val}
     78 }
     79 
     80 // WrapString turn string into Any interface
     81 func WrapString(val string) Any {
     82 	return &stringAny{baseAny{}, val}
     83 }
     84 
     85 // Wrap turn a go object into Any interface
     86 func Wrap(val interface{}) Any {
     87 	if val == nil {
     88 		return &nilAny{}
     89 	}
     90 	asAny, isAny := val.(Any)
     91 	if isAny {
     92 		return asAny
     93 	}
     94 	typ := reflect2.TypeOf(val)
     95 	switch typ.Kind() {
     96 	case reflect.Slice:
     97 		return wrapArray(val)
     98 	case reflect.Struct:
     99 		return wrapStruct(val)
    100 	case reflect.Map:
    101 		return wrapMap(val)
    102 	case reflect.String:
    103 		return WrapString(val.(string))
    104 	case reflect.Int:
    105 		if strconv.IntSize == 32 {
    106 			return WrapInt32(int32(val.(int)))
    107 		}
    108 		return WrapInt64(int64(val.(int)))
    109 	case reflect.Int8:
    110 		return WrapInt32(int32(val.(int8)))
    111 	case reflect.Int16:
    112 		return WrapInt32(int32(val.(int16)))
    113 	case reflect.Int32:
    114 		return WrapInt32(val.(int32))
    115 	case reflect.Int64:
    116 		return WrapInt64(val.(int64))
    117 	case reflect.Uint:
    118 		if strconv.IntSize == 32 {
    119 			return WrapUint32(uint32(val.(uint)))
    120 		}
    121 		return WrapUint64(uint64(val.(uint)))
    122 	case reflect.Uintptr:
    123 		if ptrSize == 32 {
    124 			return WrapUint32(uint32(val.(uintptr)))
    125 		}
    126 		return WrapUint64(uint64(val.(uintptr)))
    127 	case reflect.Uint8:
    128 		return WrapUint32(uint32(val.(uint8)))
    129 	case reflect.Uint16:
    130 		return WrapUint32(uint32(val.(uint16)))
    131 	case reflect.Uint32:
    132 		return WrapUint32(uint32(val.(uint32)))
    133 	case reflect.Uint64:
    134 		return WrapUint64(val.(uint64))
    135 	case reflect.Float32:
    136 		return WrapFloat64(float64(val.(float32)))
    137 	case reflect.Float64:
    138 		return WrapFloat64(val.(float64))
    139 	case reflect.Bool:
    140 		if val.(bool) == true {
    141 			return &trueAny{}
    142 		}
    143 		return &falseAny{}
    144 	}
    145 	return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)}
    146 }
    147 
    148 // ReadAny read next JSON element as an Any object. It is a better json.RawMessage.
    149 func (iter *Iterator) ReadAny() Any {
    150 	return iter.readAny()
    151 }
    152 
    153 func (iter *Iterator) readAny() Any {
    154 	c := iter.nextToken()
    155 	switch c {
    156 	case '"':
    157 		iter.unreadByte()
    158 		return &stringAny{baseAny{}, iter.ReadString()}
    159 	case 'n':
    160 		iter.skipThreeBytes('u', 'l', 'l') // null
    161 		return &nilAny{}
    162 	case 't':
    163 		iter.skipThreeBytes('r', 'u', 'e') // true
    164 		return &trueAny{}
    165 	case 'f':
    166 		iter.skipFourBytes('a', 'l', 's', 'e') // false
    167 		return &falseAny{}
    168 	case '{':
    169 		return iter.readObjectAny()
    170 	case '[':
    171 		return iter.readArrayAny()
    172 	case '-':
    173 		return iter.readNumberAny(false)
    174 	case 0:
    175 		return &invalidAny{baseAny{}, errors.New("input is empty")}
    176 	default:
    177 		return iter.readNumberAny(true)
    178 	}
    179 }
    180 
    181 func (iter *Iterator) readNumberAny(positive bool) Any {
    182 	iter.startCapture(iter.head - 1)
    183 	iter.skipNumber()
    184 	lazyBuf := iter.stopCapture()
    185 	return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
    186 }
    187 
    188 func (iter *Iterator) readObjectAny() Any {
    189 	iter.startCapture(iter.head - 1)
    190 	iter.skipObject()
    191 	lazyBuf := iter.stopCapture()
    192 	return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
    193 }
    194 
    195 func (iter *Iterator) readArrayAny() Any {
    196 	iter.startCapture(iter.head - 1)
    197 	iter.skipArray()
    198 	lazyBuf := iter.stopCapture()
    199 	return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
    200 }
    201 
    202 func locateObjectField(iter *Iterator, target string) []byte {
    203 	var found []byte
    204 	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
    205 		if field == target {
    206 			found = iter.SkipAndReturnBytes()
    207 			return false
    208 		}
    209 		iter.Skip()
    210 		return true
    211 	})
    212 	return found
    213 }
    214 
    215 func locateArrayElement(iter *Iterator, target int) []byte {
    216 	var found []byte
    217 	n := 0
    218 	iter.ReadArrayCB(func(iter *Iterator) bool {
    219 		if n == target {
    220 			found = iter.SkipAndReturnBytes()
    221 			return false
    222 		}
    223 		iter.Skip()
    224 		n++
    225 		return true
    226 	})
    227 	return found
    228 }
    229 
    230 func locatePath(iter *Iterator, path []interface{}) Any {
    231 	for i, pathKeyObj := range path {
    232 		switch pathKey := pathKeyObj.(type) {
    233 		case string:
    234 			valueBytes := locateObjectField(iter, pathKey)
    235 			if valueBytes == nil {
    236 				return newInvalidAny(path[i:])
    237 			}
    238 			iter.ResetBytes(valueBytes)
    239 		case int:
    240 			valueBytes := locateArrayElement(iter, pathKey)
    241 			if valueBytes == nil {
    242 				return newInvalidAny(path[i:])
    243 			}
    244 			iter.ResetBytes(valueBytes)
    245 		case int32:
    246 			if '*' == pathKey {
    247 				return iter.readAny().Get(path[i:]...)
    248 			}
    249 			return newInvalidAny(path[i:])
    250 		default:
    251 			return newInvalidAny(path[i:])
    252 		}
    253 	}
    254 	if iter.Error != nil && iter.Error != io.EOF {
    255 		return &invalidAny{baseAny{}, iter.Error}
    256 	}
    257 	return iter.readAny()
    258 }
    259 
    260 var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem()
    261 
    262 func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder {
    263 	if typ == anyType {
    264 		return &directAnyCodec{}
    265 	}
    266 	if typ.Implements(anyType) {
    267 		return &anyCodec{
    268 			valType: typ,
    269 		}
    270 	}
    271 	return nil
    272 }
    273 
    274 func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder {
    275 	if typ == anyType {
    276 		return &directAnyCodec{}
    277 	}
    278 	if typ.Implements(anyType) {
    279 		return &anyCodec{
    280 			valType: typ,
    281 		}
    282 	}
    283 	return nil
    284 }
    285 
    286 type anyCodec struct {
    287 	valType reflect2.Type
    288 }
    289 
    290 func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
    291 	panic("not implemented")
    292 }
    293 
    294 func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
    295 	obj := codec.valType.UnsafeIndirect(ptr)
    296 	any := obj.(Any)
    297 	any.WriteTo(stream)
    298 }
    299 
    300 func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool {
    301 	obj := codec.valType.UnsafeIndirect(ptr)
    302 	any := obj.(Any)
    303 	return any.Size() == 0
    304 }
    305 
    306 type directAnyCodec struct {
    307 }
    308 
    309 func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
    310 	*(*Any)(ptr) = iter.readAny()
    311 }
    312 
    313 func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
    314 	any := *(*Any)(ptr)
    315 	if any == nil {
    316 		stream.WriteNil()
    317 		return
    318 	}
    319 	any.WriteTo(stream)
    320 }
    321 
    322 func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool {
    323 	any := *(*Any)(ptr)
    324 	return any.Size() == 0
    325 }