github.com/3JoB/go-json@v0.10.4/internal/decoder/uint.go (about) 1 package decoder 2 3 import ( 4 "fmt" 5 "unsafe" 6 7 "github.com/3JoB/go-reflect" 8 "github.com/3JoB/unsafeConvert" 9 10 "github.com/3JoB/go-json/internal/errors" 11 "github.com/3JoB/go-json/internal/runtime" 12 ) 13 14 type uintDecoder struct { 15 typ *runtime.Type 16 kind reflect.Kind 17 op func(unsafe.Pointer, uint64) 18 structName string 19 fieldName string 20 } 21 22 func newUintDecoder(typ *runtime.Type, structName, fieldName string, op func(unsafe.Pointer, uint64)) *uintDecoder { 23 return &uintDecoder{ 24 typ: typ, 25 kind: typ.Kind(), 26 op: op, 27 structName: structName, 28 fieldName: fieldName, 29 } 30 } 31 32 func (d *uintDecoder) typeError(buf []byte, offset int64) *errors.UnmarshalTypeError { 33 return &errors.UnmarshalTypeError{ 34 Value: fmt.Sprintf("number %s", unsafeConvert.StringReflect(buf)), 35 Type: reflect.ToT(runtime.RType2Type(d.typ)), 36 Offset: offset, 37 } 38 } 39 40 var ( 41 pow10u64 = [...]uint64{ 42 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09, 43 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 44 } 45 pow10u64Len = len(pow10u64) 46 ) 47 48 func (d *uintDecoder) parseUint(b []byte) (uint64, error) { 49 maxDigit := len(b) 50 if maxDigit > pow10u64Len { 51 return 0, errors.New("invalid length of number") 52 } 53 sum := uint64(0) 54 for i := 0; i < maxDigit; i++ { 55 c := uint64(b[i]) - 48 56 digitValue := pow10u64[maxDigit-i-1] 57 sum += c * digitValue 58 } 59 return sum, nil 60 } 61 62 func (d *uintDecoder) decodeStreamByte(s *Stream) ([]byte, error) { 63 for { 64 switch s.char() { 65 case ' ', '\n', '\t', '\r': 66 s.cursor++ 67 continue 68 case '0': 69 s.cursor++ 70 return numZeroBuf, nil 71 case '1', '2', '3', '4', '5', '6', '7', '8', '9': 72 start := s.cursor 73 for { 74 s.cursor++ 75 if numTable[s.char()] { 76 continue 77 } else if s.char() == nul { 78 if s.read() { 79 s.cursor-- // for retry current character 80 continue 81 } 82 } 83 break 84 } 85 num := s.buf[start:s.cursor] 86 return num, nil 87 case 'n': 88 if err := nullBytes(s); err != nil { 89 return nil, err 90 } 91 return nil, nil 92 case nul: 93 if s.read() { 94 continue 95 } 96 default: 97 return nil, d.typeError([]byte{s.char()}, s.totalOffset()) 98 } 99 break 100 } 101 return nil, errors.ErrUnexpectedEndOfJSON("number(unsigned integer)", s.totalOffset()) 102 } 103 104 func (d *uintDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { 105 for { 106 switch buf[cursor] { 107 case ' ', '\n', '\t', '\r': 108 cursor++ 109 continue 110 case '0': 111 cursor++ 112 return numZeroBuf, cursor, nil 113 case '1', '2', '3', '4', '5', '6', '7', '8', '9': 114 start := cursor 115 cursor++ 116 for numTable[buf[cursor]] { 117 cursor++ 118 } 119 num := buf[start:cursor] 120 return num, cursor, nil 121 case 'n': 122 if err := validateNull(buf, cursor); err != nil { 123 return nil, 0, err 124 } 125 cursor += 4 126 return nil, cursor, nil 127 default: 128 return nil, 0, d.typeError([]byte{buf[cursor]}, cursor) 129 } 130 } 131 } 132 133 func (d *uintDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { 134 bytes, err := d.decodeStreamByte(s) 135 if err != nil { 136 return err 137 } 138 if bytes == nil { 139 return nil 140 } 141 u64, err := d.parseUint(bytes) 142 if err != nil { 143 return d.typeError(bytes, s.totalOffset()) 144 } 145 switch d.kind { 146 case reflect.Uint8: 147 if (1 << 8) <= u64 { 148 return d.typeError(bytes, s.totalOffset()) 149 } 150 case reflect.Uint16: 151 if (1 << 16) <= u64 { 152 return d.typeError(bytes, s.totalOffset()) 153 } 154 case reflect.Uint32: 155 if (1 << 32) <= u64 { 156 return d.typeError(bytes, s.totalOffset()) 157 } 158 } 159 d.op(p, u64) 160 return nil 161 } 162 163 func (d *uintDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { 164 bytes, c, err := d.decodeByte(ctx.Buf, cursor) 165 if err != nil { 166 return 0, err 167 } 168 if bytes == nil { 169 return c, nil 170 } 171 cursor = c 172 u64, err := d.parseUint(bytes) 173 if err != nil { 174 return 0, d.typeError(bytes, cursor) 175 } 176 switch d.kind { 177 case reflect.Uint8: 178 if (1 << 8) <= u64 { 179 return 0, d.typeError(bytes, cursor) 180 } 181 case reflect.Uint16: 182 if (1 << 16) <= u64 { 183 return 0, d.typeError(bytes, cursor) 184 } 185 case reflect.Uint32: 186 if (1 << 32) <= u64 { 187 return 0, d.typeError(bytes, cursor) 188 } 189 } 190 d.op(p, u64) 191 return cursor, nil 192 } 193 194 func (d *uintDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { 195 return nil, 0, errors.New("json: uint decoder does not support decode path") 196 }