json_parser.go raw
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 }
390