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