gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

int.go (5109B)


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