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  }