github.com/alibabacloud-go/tea@v1.3.10/dara/json_parser.go (about) 1 package dara 2 3 import ( 4 "bytes" 5 "encoding/json" 6 jsoniter "github.com/json-iterator/go" 7 "github.com/modern-go/reflect2" 8 "io" 9 "io/ioutil" 10 "math" 11 "reflect" 12 "strconv" 13 "strings" 14 "unsafe" 15 ) 16 17 const maxUint = ^uint(0) 18 const maxInt = int(maxUint >> 1) 19 const minInt = -maxInt - 1 20 21 var jsonParser jsoniter.API 22 23 func init() { 24 jsonParser = jsoniter.Config{ 25 EscapeHTML: true, 26 SortMapKeys: true, 27 ValidateJsonRawMessage: true, 28 CaseSensitive: true, 29 }.Froze() 30 31 jsonParser.RegisterExtension(newBetterFuzzyExtension()) 32 } 33 34 func newBetterFuzzyExtension() jsoniter.DecoderExtension { 35 return jsoniter.DecoderExtension{ 36 reflect2.DefaultTypeOfKind(reflect.String): &nullableFuzzyStringDecoder{}, 37 reflect2.DefaultTypeOfKind(reflect.Bool): &fuzzyBoolDecoder{}, 38 reflect2.DefaultTypeOfKind(reflect.Float32): &nullableFuzzyFloat32Decoder{}, 39 reflect2.DefaultTypeOfKind(reflect.Float64): &nullableFuzzyFloat64Decoder{}, 40 reflect2.DefaultTypeOfKind(reflect.Int): &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { 41 if isFloat { 42 val := iter.ReadFloat64() 43 if val > float64(maxInt) || val < float64(minInt) { 44 iter.ReportError("fuzzy decode int", "exceed range") 45 return 46 } 47 *((*int)(ptr)) = int(val) 48 } else { 49 *((*int)(ptr)) = iter.ReadInt() 50 } 51 }}, 52 reflect2.DefaultTypeOfKind(reflect.Uint): &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { 53 if isFloat { 54 val := iter.ReadFloat64() 55 if val > float64(maxUint) || val < 0 { 56 iter.ReportError("fuzzy decode uint", "exceed range") 57 return 58 } 59 *((*uint)(ptr)) = uint(val) 60 } else { 61 *((*uint)(ptr)) = iter.ReadUint() 62 } 63 }}, 64 reflect2.DefaultTypeOfKind(reflect.Int8): &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { 65 if isFloat { 66 val := iter.ReadFloat64() 67 if val > float64(math.MaxInt8) || val < float64(math.MinInt8) { 68 iter.ReportError("fuzzy decode int8", "exceed range") 69 return 70 } 71 *((*int8)(ptr)) = int8(val) 72 } else { 73 *((*int8)(ptr)) = iter.ReadInt8() 74 } 75 }}, 76 reflect2.DefaultTypeOfKind(reflect.Uint8): &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { 77 if isFloat { 78 val := iter.ReadFloat64() 79 if val > float64(math.MaxUint8) || val < 0 { 80 iter.ReportError("fuzzy decode uint8", "exceed range") 81 return 82 } 83 *((*uint8)(ptr)) = uint8(val) 84 } else { 85 *((*uint8)(ptr)) = iter.ReadUint8() 86 } 87 }}, 88 reflect2.DefaultTypeOfKind(reflect.Int16): &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { 89 if isFloat { 90 val := iter.ReadFloat64() 91 if val > float64(math.MaxInt16) || val < float64(math.MinInt16) { 92 iter.ReportError("fuzzy decode int16", "exceed range") 93 return 94 } 95 *((*int16)(ptr)) = int16(val) 96 } else { 97 *((*int16)(ptr)) = iter.ReadInt16() 98 } 99 }}, 100 reflect2.DefaultTypeOfKind(reflect.Uint16): &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { 101 if isFloat { 102 val := iter.ReadFloat64() 103 if val > float64(math.MaxUint16) || val < 0 { 104 iter.ReportError("fuzzy decode uint16", "exceed range") 105 return 106 } 107 *((*uint16)(ptr)) = uint16(val) 108 } else { 109 *((*uint16)(ptr)) = iter.ReadUint16() 110 } 111 }}, 112 reflect2.DefaultTypeOfKind(reflect.Int32): &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { 113 if isFloat { 114 val := iter.ReadFloat64() 115 if val > float64(math.MaxInt32) || val < float64(math.MinInt32) { 116 iter.ReportError("fuzzy decode int32", "exceed range") 117 return 118 } 119 *((*int32)(ptr)) = int32(val) 120 } else { 121 *((*int32)(ptr)) = iter.ReadInt32() 122 } 123 }}, 124 reflect2.DefaultTypeOfKind(reflect.Uint32): &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { 125 if isFloat { 126 val := iter.ReadFloat64() 127 if val > float64(math.MaxUint32) || val < 0 { 128 iter.ReportError("fuzzy decode uint32", "exceed range") 129 return 130 } 131 *((*uint32)(ptr)) = uint32(val) 132 } else { 133 *((*uint32)(ptr)) = iter.ReadUint32() 134 } 135 }}, 136 reflect2.DefaultTypeOfKind(reflect.Int64): &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { 137 if isFloat { 138 val := iter.ReadFloat64() 139 if val > float64(math.MaxInt64) || val < float64(math.MinInt64) { 140 iter.ReportError("fuzzy decode int64", "exceed range") 141 return 142 } 143 *((*int64)(ptr)) = int64(val) 144 } else { 145 *((*int64)(ptr)) = iter.ReadInt64() 146 } 147 }}, 148 reflect2.DefaultTypeOfKind(reflect.Uint64): &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { 149 if isFloat { 150 val := iter.ReadFloat64() 151 if val > float64(math.MaxUint64) || val < 0 { 152 iter.ReportError("fuzzy decode uint64", "exceed range") 153 return 154 } 155 *((*uint64)(ptr)) = uint64(val) 156 } else { 157 *((*uint64)(ptr)) = iter.ReadUint64() 158 } 159 }}, 160 } 161 } 162 163 type nullableFuzzyStringDecoder struct { 164 } 165 166 func (decoder *nullableFuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { 167 valueType := iter.WhatIsNext() 168 switch valueType { 169 case jsoniter.NumberValue: 170 var number json.Number 171 iter.ReadVal(&number) 172 *((*string)(ptr)) = string(number) 173 case jsoniter.StringValue: 174 *((*string)(ptr)) = iter.ReadString() 175 case jsoniter.BoolValue: 176 *((*string)(ptr)) = strconv.FormatBool(iter.ReadBool()) 177 case jsoniter.NilValue: 178 iter.ReadNil() 179 *((*string)(ptr)) = "" 180 default: 181 iter.ReportError("fuzzyStringDecoder", "not number or string or bool") 182 } 183 } 184 185 type fuzzyBoolDecoder struct { 186 } 187 188 func (decoder *fuzzyBoolDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { 189 valueType := iter.WhatIsNext() 190 switch valueType { 191 case jsoniter.BoolValue: 192 *((*bool)(ptr)) = iter.ReadBool() 193 case jsoniter.NumberValue: 194 var number json.Number 195 iter.ReadVal(&number) 196 num, err := number.Int64() 197 if err != nil { 198 iter.ReportError("fuzzyBoolDecoder", "get value from json.number failed") 199 } 200 if num == 0 { 201 *((*bool)(ptr)) = false 202 } else { 203 *((*bool)(ptr)) = true 204 } 205 case jsoniter.StringValue: 206 strValue := strings.ToLower(iter.ReadString()) 207 if strValue == "true" { 208 *((*bool)(ptr)) = true 209 } else if strValue == "false" || strValue == "" { 210 *((*bool)(ptr)) = false 211 } else { 212 iter.ReportError("fuzzyBoolDecoder", "unsupported bool value: "+strValue) 213 } 214 case jsoniter.NilValue: 215 iter.ReadNil() 216 *((*bool)(ptr)) = false 217 default: 218 iter.ReportError("fuzzyBoolDecoder", "not number or string or nil") 219 } 220 } 221 222 type nullableFuzzyIntegerDecoder struct { 223 fun func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) 224 } 225 226 func (decoder *nullableFuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { 227 valueType := iter.WhatIsNext() 228 var str string 229 switch valueType { 230 case jsoniter.NumberValue: 231 var number json.Number 232 iter.ReadVal(&number) 233 str = string(number) 234 case jsoniter.StringValue: 235 str = iter.ReadString() 236 // support empty string 237 if str == "" { 238 str = "0" 239 } 240 case jsoniter.BoolValue: 241 if iter.ReadBool() { 242 str = "1" 243 } else { 244 str = "0" 245 } 246 case jsoniter.NilValue: 247 iter.ReadNil() 248 str = "0" 249 default: 250 iter.ReportError("fuzzyIntegerDecoder", "not number or string") 251 } 252 newIter := iter.Pool().BorrowIterator([]byte(str)) 253 defer iter.Pool().ReturnIterator(newIter) 254 isFloat := strings.IndexByte(str, '.') != -1 255 decoder.fun(isFloat, ptr, newIter) 256 if newIter.Error != nil && newIter.Error != io.EOF { 257 iter.Error = newIter.Error 258 } 259 } 260 261 type nullableFuzzyFloat32Decoder struct { 262 } 263 264 func (decoder *nullableFuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { 265 valueType := iter.WhatIsNext() 266 var str string 267 switch valueType { 268 case jsoniter.NumberValue: 269 *((*float32)(ptr)) = iter.ReadFloat32() 270 case jsoniter.StringValue: 271 str = iter.ReadString() 272 // support empty string 273 if str == "" { 274 *((*float32)(ptr)) = 0 275 return 276 } 277 newIter := iter.Pool().BorrowIterator([]byte(str)) 278 defer iter.Pool().ReturnIterator(newIter) 279 *((*float32)(ptr)) = newIter.ReadFloat32() 280 if newIter.Error != nil && newIter.Error != io.EOF { 281 iter.Error = newIter.Error 282 } 283 case jsoniter.BoolValue: 284 // support bool to float32 285 if iter.ReadBool() { 286 *((*float32)(ptr)) = 1 287 } else { 288 *((*float32)(ptr)) = 0 289 } 290 case jsoniter.NilValue: 291 iter.ReadNil() 292 *((*float32)(ptr)) = 0 293 default: 294 iter.ReportError("nullableFuzzyFloat32Decoder", "not number or string") 295 } 296 } 297 298 type nullableFuzzyFloat64Decoder struct { 299 } 300 301 func (decoder *nullableFuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { 302 valueType := iter.WhatIsNext() 303 var str string 304 switch valueType { 305 case jsoniter.NumberValue: 306 *((*float64)(ptr)) = iter.ReadFloat64() 307 case jsoniter.StringValue: 308 str = iter.ReadString() 309 // support empty string 310 if str == "" { 311 *((*float64)(ptr)) = 0 312 return 313 } 314 newIter := iter.Pool().BorrowIterator([]byte(str)) 315 defer iter.Pool().ReturnIterator(newIter) 316 *((*float64)(ptr)) = newIter.ReadFloat64() 317 if newIter.Error != nil && newIter.Error != io.EOF { 318 iter.Error = newIter.Error 319 } 320 case jsoniter.BoolValue: 321 // support bool to float64 322 if iter.ReadBool() { 323 *((*float64)(ptr)) = 1 324 } else { 325 *((*float64)(ptr)) = 0 326 } 327 case jsoniter.NilValue: 328 // support empty string 329 iter.ReadNil() 330 *((*float64)(ptr)) = 0 331 default: 332 iter.ReportError("nullableFuzzyFloat64Decoder", "not number or string") 333 } 334 } 335 336 func Stringify(a interface{}) string { 337 switch v := a.(type) { 338 case *string: 339 return StringValue(v) 340 case string: 341 return v 342 case []byte: 343 return string(v) 344 case io.Reader: 345 byt, err := ioutil.ReadAll(v) 346 if err != nil { 347 return "" 348 } 349 return string(byt) 350 } 351 byt := bytes.NewBuffer([]byte{}) 352 jsonEncoder := json.NewEncoder(byt) 353 jsonEncoder.SetEscapeHTML(false) 354 if err := jsonEncoder.Encode(a); err != nil { 355 return "" 356 } 357 return string(bytes.TrimSpace(byt.Bytes())) 358 } 359 360 func ParseJSON(a string) interface{} { 361 mapTmp := make(map[string]interface{}) 362 d := json.NewDecoder(bytes.NewReader([]byte(a))) 363 d.UseNumber() 364 err := d.Decode(&mapTmp) 365 if err == nil { 366 return mapTmp 367 } 368 369 sliceTmp := make([]interface{}, 0) 370 d = json.NewDecoder(bytes.NewReader([]byte(a))) 371 d.UseNumber() 372 err = d.Decode(&sliceTmp) 373 if err == nil { 374 return sliceTmp 375 } 376 377 if num, err := strconv.Atoi(a); err == nil { 378 return num 379 } 380 381 if ok, err := strconv.ParseBool(a); err == nil { 382 return ok 383 } 384 385 if floa64tVal, err := strconv.ParseFloat(a, 64); err == nil { 386 return floa64tVal 387 } 388 return nil 389 }