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