github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/iterator_int16.go (about) 1 package jzon 2 3 import ( 4 "io" 5 "math" 6 "strconv" 7 ) 8 9 const ( 10 maxUint16Div10NumDigits = 4 11 maxUint16Div10 = uint16(math.MaxUint16) / 10 12 maxUint16Mod10 = int8(math.MaxUint16 - maxUint16Div10*10) 13 ) 14 15 // ReadUint16 reads an uint16 value 16 func (it *Iterator) ReadUint16() (uint16, error) { 17 c, err := it.nextToken() 18 if err != nil { 19 return 0, err 20 } 21 it.head++ 22 return it.readUint16(c) 23 } 24 25 func (it *Iterator) readUint16(c byte) (ret uint16, 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 = uint16(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 ret, nil 42 } 43 if numDigit >= maxUint16Div10NumDigits { 44 if ret > maxUint16Div10 || 45 (ret == maxUint16Div10 && digit > maxUint16Mod10) { 46 it.head = i 47 err = IntOverflowError{} 48 return 49 } 50 } 51 ret = (ret << 3) + (ret << 1) + uint16(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) readInt16(c byte) (int16, 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.readUint16(c) 72 if err != nil { 73 return 0, err 74 } 75 if v > math.MaxInt16+1 { 76 return 0, IntOverflowError{ 77 typ: "int16", 78 value: "-" + strconv.FormatUint(uint64(v), 10), 79 } 80 } 81 return -int16(v), nil 82 } 83 v, err := it.readUint16(c) 84 if err != nil { 85 return 0, err 86 } 87 if v > math.MaxInt16 { 88 return 0, IntOverflowError{ 89 typ: "int16", 90 value: strconv.FormatUint(uint64(v), 10), 91 } 92 } 93 return int16(v), nil 94 } 95 96 // ReadInt16 reads an int16 value 97 func (it *Iterator) ReadInt16() (int16, error) { 98 c, err := it.nextToken() 99 if err != nil { 100 return 0, err 101 } 102 it.head++ 103 return it.readInt16(c) 104 }