github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/iterator_int32.go (about)

     1  package jzon
     2  
     3  import (
     4  	"io"
     5  	"math"
     6  	"strconv"
     7  )
     8  
     9  const (
    10  	maxUint32Div10NumDigits = 9
    11  	maxUint32Div10          = uint32(math.MaxUint32) / 10
    12  	maxUint32Mod10          = int8(math.MaxUint32 - maxUint32Div10*10)
    13  )
    14  
    15  // ReadUint32 reads an uint32 value
    16  func (it *Iterator) ReadUint32() (uint32, error) {
    17  	c, err := it.nextToken()
    18  	if err != nil {
    19  		return 0, err
    20  	}
    21  	it.head++
    22  	return it.readUint32(c)
    23  }
    24  
    25  func (it *Iterator) readUint32(c byte) (ret uint32, err error) {
    26  	u := intDigits[c]
    27  	if u == 0 {
    28  		return 0, nil
    29  	}
    30  	if u == invalidDigit {
    31  		return 0, InvalidDigitError{c: c}
    32  	}
    33  	ret = uint32(u)
    34  	numDigit := 1
    35  	for {
    36  		i := it.head
    37  		for ; i < it.tail; i++ {
    38  			digit := intDigits[it.buffer[i]]
    39  			if digit == invalidDigit {
    40  				it.head = i
    41  				return
    42  			}
    43  			if numDigit >= maxUint32Div10NumDigits {
    44  				if ret > maxUint32Div10 ||
    45  					(ret == maxUint32Div10 && digit > maxUint32Mod10) {
    46  					it.head = i
    47  					err = IntOverflowError{}
    48  					return
    49  				}
    50  			}
    51  			ret = (ret << 3) + (ret << 1) + uint32(digit)
    52  			numDigit++
    53  		}
    54  		it.head = i
    55  		if err = it.readMore(); err != nil {
    56  			if err == io.EOF {
    57  				err = nil
    58  			}
    59  			return
    60  		}
    61  	}
    62  }
    63  
    64  func (it *Iterator) readInt32(c byte) (int32, error) {
    65  	if c == '-' {
    66  		c, err := it.nextByte()
    67  		if err != nil {
    68  			return 0, err
    69  		}
    70  		it.head++
    71  		v, err := it.readUint32(c)
    72  		if err != nil {
    73  			return 0, err
    74  		}
    75  		if v > math.MaxInt32+1 {
    76  			return 0, IntOverflowError{
    77  				typ:   "int32",
    78  				value: "-" + strconv.FormatUint(uint64(v), 10),
    79  			}
    80  		}
    81  		return -int32(v), nil
    82  	}
    83  	v, err := it.readUint32(c)
    84  	if err != nil {
    85  		return 0, err
    86  	}
    87  	if v > math.MaxInt32 {
    88  		return 0, IntOverflowError{
    89  			typ:   "int32",
    90  			value: strconv.FormatUint(uint64(v), 10),
    91  		}
    92  	}
    93  	return int32(v), nil
    94  }
    95  
    96  // ReadInt32 reads an int32 value
    97  func (it *Iterator) ReadInt32() (int32, error) {
    98  	c, err := it.nextToken()
    99  	if err != nil {
   100  		return 0, err
   101  	}
   102  	it.head++
   103  	return it.readInt32(c)
   104  }