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

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