1package jsoniter 2 3import ( 4 "fmt" 5 "io" 6 "reflect" 7) 8 9// Any generic object representation. 10// The lazy json implementation holds []byte and parse lazily. 11type Any interface { 12 LastError() error 13 ValueType() ValueType 14 MustBeValid() Any 15 ToBool() bool 16 ToInt() int 17 ToInt32() int32 18 ToInt64() int64 19 ToUint() uint 20 ToUint32() uint32 21 ToUint64() uint64 22 ToFloat32() float32 23 ToFloat64() float64 24 ToString() string 25 ToVal(val interface{}) 26 Get(path ...interface{}) Any 27 // TODO: add Set 28 Size() int 29 Keys() []string 30 GetInterface() interface{} 31 WriteTo(stream *Stream) 32} 33 34type baseAny struct{} 35 36func (any *baseAny) Get(path ...interface{}) Any { 37 return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)} 38} 39 40func (any *baseAny) Size() int { 41 return 0 42} 43 44func (any *baseAny) Keys() []string { 45 return []string{} 46} 47 48func (any *baseAny) ToVal(obj interface{}) { 49 panic("not implemented") 50} 51 52// WrapInt32 turn int32 into Any interface 53func WrapInt32(val int32) Any { 54 return &int32Any{baseAny{}, val} 55} 56 57// WrapInt64 turn int64 into Any interface 58func WrapInt64(val int64) Any { 59 return &int64Any{baseAny{}, val} 60} 61 62// WrapUint32 turn uint32 into Any interface 63func WrapUint32(val uint32) Any { 64 return &uint32Any{baseAny{}, val} 65} 66 67// WrapUint64 turn uint64 into Any interface 68func WrapUint64(val uint64) Any { 69 return &uint64Any{baseAny{}, val} 70} 71 72// WrapFloat64 turn float64 into Any interface 73func WrapFloat64(val float64) Any { 74 return &floatAny{baseAny{}, val} 75} 76 77// WrapString turn string into Any interface 78func WrapString(val string) Any { 79 return &stringAny{baseAny{}, val} 80} 81 82// Wrap turn a go object into Any interface 83func Wrap(val interface{}) Any { 84 if val == nil { 85 return &nilAny{} 86 } 87 asAny, isAny := val.(Any) 88 if isAny { 89 return asAny 90 } 91 typ := reflect.TypeOf(val) 92 switch typ.Kind() { 93 case reflect.Slice: 94 return wrapArray(val) 95 case reflect.Struct: 96 return wrapStruct(val) 97 case reflect.Map: 98 return wrapMap(val) 99 case reflect.String: 100 return WrapString(val.(string)) 101 case reflect.Int: 102 return WrapInt64(int64(val.(int))) 103 case reflect.Int8: 104 return WrapInt32(int32(val.(int8))) 105 case reflect.Int16: 106 return WrapInt32(int32(val.(int16))) 107 case reflect.Int32: 108 return WrapInt32(val.(int32)) 109 case reflect.Int64: 110 return WrapInt64(val.(int64)) 111 case reflect.Uint: 112 return WrapUint64(uint64(val.(uint))) 113 case reflect.Uint8: 114 return WrapUint32(uint32(val.(uint8))) 115 case reflect.Uint16: 116 return WrapUint32(uint32(val.(uint16))) 117 case reflect.Uint32: 118 return WrapUint32(uint32(val.(uint32))) 119 case reflect.Uint64: 120 return WrapUint64(val.(uint64)) 121 case reflect.Float32: 122 return WrapFloat64(float64(val.(float32))) 123 case reflect.Float64: 124 return WrapFloat64(val.(float64)) 125 case reflect.Bool: 126 if val.(bool) == true { 127 return &trueAny{} 128 } 129 return &falseAny{} 130 } 131 return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)} 132} 133 134// ReadAny read next JSON element as an Any object. It is a better json.RawMessage. 135func (iter *Iterator) ReadAny() Any { 136 return iter.readAny() 137} 138 139func (iter *Iterator) readAny() Any { 140 c := iter.nextToken() 141 switch c { 142 case '"': 143 iter.unreadByte() 144 return &stringAny{baseAny{}, iter.ReadString()} 145 case 'n': 146 iter.skipThreeBytes('u', 'l', 'l') // null 147 return &nilAny{} 148 case 't': 149 iter.skipThreeBytes('r', 'u', 'e') // true 150 return &trueAny{} 151 case 'f': 152 iter.skipFourBytes('a', 'l', 's', 'e') // false 153 return &falseAny{} 154 case '{': 155 return iter.readObjectAny() 156 case '[': 157 return iter.readArrayAny() 158 case '-': 159 return iter.readNumberAny(false) 160 default: 161 return iter.readNumberAny(true) 162 } 163} 164 165func (iter *Iterator) readNumberAny(positive bool) Any { 166 iter.startCapture(iter.head - 1) 167 iter.skipNumber() 168 lazyBuf := iter.stopCapture() 169 return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} 170} 171 172func (iter *Iterator) readObjectAny() Any { 173 iter.startCapture(iter.head - 1) 174 iter.skipObject() 175 lazyBuf := iter.stopCapture() 176 return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} 177} 178 179func (iter *Iterator) readArrayAny() Any { 180 iter.startCapture(iter.head - 1) 181 iter.skipArray() 182 lazyBuf := iter.stopCapture() 183 return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} 184} 185 186func locateObjectField(iter *Iterator, target string) []byte { 187 var found []byte 188 iter.ReadObjectCB(func(iter *Iterator, field string) bool { 189 if field == target { 190 found = iter.SkipAndReturnBytes() 191 return false 192 } 193 iter.Skip() 194 return true 195 }) 196 return found 197} 198 199func locateArrayElement(iter *Iterator, target int) []byte { 200 var found []byte 201 n := 0 202 iter.ReadArrayCB(func(iter *Iterator) bool { 203 if n == target { 204 found = iter.SkipAndReturnBytes() 205 return false 206 } 207 iter.Skip() 208 n++ 209 return true 210 }) 211 return found 212} 213 214func locatePath(iter *Iterator, path []interface{}) Any { 215 for i, pathKeyObj := range path { 216 switch pathKey := pathKeyObj.(type) { 217 case string: 218 valueBytes := locateObjectField(iter, pathKey) 219 if valueBytes == nil { 220 return newInvalidAny(path[i:]) 221 } 222 iter.ResetBytes(valueBytes) 223 case int: 224 valueBytes := locateArrayElement(iter, pathKey) 225 if valueBytes == nil { 226 return newInvalidAny(path[i:]) 227 } 228 iter.ResetBytes(valueBytes) 229 case int32: 230 if '*' == pathKey { 231 return iter.readAny().Get(path[i:]...) 232 } 233 return newInvalidAny(path[i:]) 234 default: 235 return newInvalidAny(path[i:]) 236 } 237 } 238 if iter.Error != nil && iter.Error != io.EOF { 239 return &invalidAny{baseAny{}, iter.Error} 240 } 241 return iter.readAny() 242} 243