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