| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- package extra
- import (
- "github.com/json-iterator/go"
- "unsafe"
- "encoding/json"
- "strings"
- )
- const MaxUint = ^uint(0)
- const MinUint = 0
- const MaxInt = int(MaxUint >> 1)
- const MinInt = -MaxInt - 1
- func RegisterFuzzyDecoders() {
- jsoniter.RegisterTypeDecoder("string", &FuzzyStringDecoder{})
- jsoniter.RegisterTypeDecoder("int", &FuzzyNumberDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator, errorReporter *jsoniter.Iterator) {
- if isFloat {
- val := iter.ReadFloat64()
- if val > float64(MaxInt) || val < float64(MinInt) {
- errorReporter.ReportError("fuzzy decode int", "exceed range")
- return
- }
- *((*int)(ptr)) = int(val)
- } else {
- *((*int)(ptr)) = iter.ReadInt()
- }
- }})
- }
- type FuzzyStringDecoder struct {
- }
- func (decoder *FuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
- valueType := iter.WhatIsNext()
- switch valueType {
- case jsoniter.Number:
- var number json.Number
- iter.ReadVal(&number)
- *((*string)(ptr)) = string(number)
- case jsoniter.String:
- *((*string)(ptr)) = iter.ReadString()
- default:
- iter.ReportError("FuzzyStringDecoder", "not number or string")
- }
- }
- type FuzzyNumberDecoder struct {
- fun func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator, errorReporter *jsoniter.Iterator)
- }
- func (decoder *FuzzyNumberDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
- valueType := iter.WhatIsNext()
- var str string
- switch valueType {
- case jsoniter.Number:
- var number json.Number
- iter.ReadVal(&number)
- str = string(number)
- case jsoniter.String:
- str = iter.ReadString()
- default:
- iter.ReportError("FuzzyNumberDecoder", "not number or string")
- }
- newIter := iter.Config().BorrowIterator([]byte(str))
- defer iter.Config().ReturnIterator(newIter)
- isFloat := strings.IndexByte(str, '.') != -1
- decoder.fun(isFloat, ptr, newIter, iter)
- }
|