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 }