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 }