gtsocial-umbx

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

uint.go (4258B)


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