github.com/3JoB/go-json@v0.10.4/internal/decoder/int.go (about) 1 package decoder 2 3 import ( 4 "fmt" 5 "unsafe" 6 7 "github.com/3JoB/go-reflect" 8 9 "github.com/3JoB/go-json/internal/errors" 10 "github.com/3JoB/go-json/internal/runtime" 11 ) 12 13 type intDecoder struct { 14 typ *runtime.Type 15 kind reflect.Kind 16 op func(unsafe.Pointer, int64) 17 structName string 18 fieldName string 19 } 20 21 func newIntDecoder(typ *runtime.Type, structName, fieldName string, op func(unsafe.Pointer, int64)) *intDecoder { 22 if typ != nil { 23 return &intDecoder{ 24 typ: typ, 25 kind: typ.Kind(), 26 op: op, 27 structName: structName, 28 fieldName: fieldName, 29 } 30 } 31 return &intDecoder{ 32 op: op, 33 structName: structName, 34 fieldName: fieldName, 35 } 36 } 37 38 func (d *intDecoder) typeError(buf []byte, offset int64) *errors.UnmarshalTypeError { 39 return &errors.UnmarshalTypeError{ 40 Value: fmt.Sprintf("number %s", string(buf)), 41 Type: reflect.ToT(runtime.RType2Type(d.typ)), 42 Struct: d.structName, 43 Field: d.fieldName, 44 Offset: offset, 45 } 46 } 47 48 var ( 49 pow10i64 = [...]int64{ 50 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09, 51 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 52 } 53 pow10i64Len = len(pow10i64) 54 ) 55 56 func (d *intDecoder) parseInt(b []byte) (int64, error) { 57 isNegative := false 58 if b[0] == '-' { 59 b = b[1:] 60 isNegative = true 61 } 62 maxDigit := len(b) 63 if maxDigit > pow10i64Len { 64 return 0, errors.New("invalid length of number") 65 } 66 sum := int64(0) 67 for i := 0; i < maxDigit; i++ { 68 c := int64(b[i]) - 48 69 digitValue := pow10i64[maxDigit-i-1] 70 sum += c * digitValue 71 } 72 if isNegative { 73 return -1 * sum, nil 74 } 75 return sum, nil 76 } 77 78 var ( 79 numTable = [256]bool{ 80 '0': true, 81 '1': true, 82 '2': true, 83 '3': true, 84 '4': true, 85 '5': true, 86 '6': true, 87 '7': true, 88 '8': true, 89 '9': true, 90 } 91 ) 92 93 var ( 94 numZeroBuf = []byte{'0'} 95 ) 96 97 func (d *intDecoder) decodeStreamByte(s *Stream) ([]byte, error) { 98 for { 99 switch s.char() { 100 case ' ', '\n', '\t', '\r': 101 s.cursor++ 102 continue 103 case '-': 104 start := s.cursor 105 for { 106 s.cursor++ 107 if numTable[s.char()] { 108 continue 109 } else if s.char() == nul { 110 if s.read() { 111 s.cursor-- // for retry current character 112 continue 113 } 114 } 115 break 116 } 117 num := s.buf[start:s.cursor] 118 if len(num) < 2 { 119 goto ERROR 120 } 121 return num, nil 122 case '0': 123 s.cursor++ 124 return numZeroBuf, nil 125 case '1', '2', '3', '4', '5', '6', '7', '8', '9': 126 start := s.cursor 127 for { 128 s.cursor++ 129 if numTable[s.char()] { 130 continue 131 } else if s.char() == nul { 132 if s.read() { 133 s.cursor-- // for retry current character 134 continue 135 } 136 } 137 break 138 } 139 num := s.buf[start:s.cursor] 140 return num, nil 141 case 'n': 142 if err := nullBytes(s); err != nil { 143 return nil, err 144 } 145 return nil, nil 146 case nul: 147 if s.read() { 148 continue 149 } 150 goto ERROR 151 default: 152 return nil, d.typeError([]byte{s.char()}, s.totalOffset()) 153 } 154 } 155 ERROR: 156 return nil, errors.ErrUnexpectedEndOfJSON("number(integer)", s.totalOffset()) 157 } 158 159 func (d *intDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { 160 b := (*sliceHeader)(unsafe.Pointer(&buf)).data 161 for { 162 switch char(b, cursor) { 163 case ' ', '\n', '\t', '\r': 164 cursor++ 165 continue 166 case '0': 167 cursor++ 168 return numZeroBuf, cursor, nil 169 case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': 170 start := cursor 171 cursor++ 172 for numTable[char(b, cursor)] { 173 cursor++ 174 } 175 num := buf[start:cursor] 176 return num, cursor, nil 177 case 'n': 178 if err := validateNull(buf, cursor); err != nil { 179 return nil, 0, err 180 } 181 cursor += 4 182 return nil, cursor, nil 183 default: 184 return nil, 0, d.typeError([]byte{char(b, cursor)}, cursor) 185 } 186 } 187 } 188 189 func (d *intDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { 190 bytes, err := d.decodeStreamByte(s) 191 if err != nil { 192 return err 193 } 194 if bytes == nil { 195 return nil 196 } 197 i64, err := d.parseInt(bytes) 198 if err != nil { 199 return d.typeError(bytes, s.totalOffset()) 200 } 201 if d.typ != nil { 202 switch d.kind { 203 case reflect.Int8: 204 if i64 < -1*(1<<7) || (1<<7) <= i64 { 205 return d.typeError(bytes, s.totalOffset()) 206 } 207 case reflect.Int16: 208 if i64 < -1*(1<<15) || (1<<15) <= i64 { 209 return d.typeError(bytes, s.totalOffset()) 210 } 211 case reflect.Int32: 212 if i64 < -1*(1<<31) || (1<<31) <= i64 { 213 return d.typeError(bytes, s.totalOffset()) 214 } 215 } 216 } 217 d.op(p, i64) 218 s.reset() 219 return nil 220 } 221 222 func (d *intDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { 223 bytes, c, err := d.decodeByte(ctx.Buf, cursor) 224 if err != nil { 225 return 0, err 226 } 227 if bytes == nil { 228 return c, nil 229 } 230 cursor = c 231 232 i64, err := d.parseInt(bytes) 233 if err != nil { 234 return 0, d.typeError(bytes, cursor) 235 } 236 if d.typ != nil { 237 switch d.kind { 238 case reflect.Int8: 239 if i64 < -1*(1<<7) || (1<<7) <= i64 { 240 return 0, d.typeError(bytes, cursor) 241 } 242 case reflect.Int16: 243 if i64 < -1*(1<<15) || (1<<15) <= i64 { 244 return 0, d.typeError(bytes, cursor) 245 } 246 case reflect.Int32: 247 if i64 < -1*(1<<31) || (1<<31) <= i64 { 248 return 0, d.typeError(bytes, cursor) 249 } 250 } 251 } 252 d.op(p, i64) 253 return cursor, nil 254 } 255 256 func (d *intDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { 257 return nil, 0, errors.New("json: int decoder does not support decode path") 258 }