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  }