github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/iterator_float32.go (about) 1 package jzon 2 3 import ( 4 "io" 5 "strconv" 6 ) 7 8 // ReadFloat32 reads a float32 value 9 func (it *Iterator) ReadFloat32() (float32, error) { 10 c, err := it.nextToken() 11 if err != nil { 12 return 0, err 13 } 14 it.head++ 15 if c == '-' { 16 c, err = it.nextByte() 17 if err != nil { 18 return 0, err 19 } 20 it.head++ 21 f, buf, err := it.readPositiveFloat32(c, it.tmpBuffer[:0]) 22 it.tmpBuffer = buf 23 return -f, err 24 } 25 f, buf, err := it.readPositiveFloat32(c, it.tmpBuffer[:0]) 26 it.tmpBuffer = buf 27 return f, err 28 } 29 30 func (it *Iterator) parseFloat32(buf []byte) (ret float32, err error) { 31 f, err := strconv.ParseFloat(localByteToString(buf), 32) 32 return float32(f), err 33 } 34 35 func (it *Iterator) readFloat32ExponentPart(buf []byte) (ret float32, _ []byte, err error) { 36 c, err := it.nextByte() 37 if err != nil { 38 return 0, buf, err 39 } 40 it.head++ 41 if c == '+' || c == '-' { 42 buf = append(buf, c) 43 c, err = it.nextByte() 44 if err != nil { 45 return 0, buf, err 46 } 47 it.head++ 48 } 49 if intDigits[c] == invalidDigit { 50 return 0, buf, InvalidFloatError{c: c} 51 } 52 buf = append(buf, c) 53 for { 54 i := it.head 55 for ; i < it.tail; i++ { 56 c = it.buffer[i] 57 digit := intDigits[c] 58 if digit == invalidDigit { 59 buf = append(buf, it.buffer[it.head:i]...) 60 it.head = i 61 ret, err = it.parseFloat32(buf) 62 return ret, buf, err 63 } 64 } 65 // i == it.tail 66 buf = append(buf, it.buffer[it.head:i]...) 67 it.head = i 68 if err = it.readMore(); err != nil { 69 if err == io.EOF { 70 ret, err = it.parseFloat32(buf) 71 return ret, buf, err 72 } 73 return 0, buf, err 74 } 75 } 76 } 77 78 func (it *Iterator) readFloat32FractionPart(buf []byte) (ret float32, _ []byte, err error) { 79 c, err := it.nextByte() 80 if err != nil { 81 return 0, buf, err 82 } 83 if intDigits[c] == invalidDigit { 84 return 0, buf, InvalidFloatError{c: c} 85 } 86 it.head++ 87 buf = append(buf, c) 88 for { 89 i := it.head 90 for ; i < it.tail; i++ { 91 c = it.buffer[i] 92 digit := floatDigits[c] 93 if digit < 0 { 94 switch digit { 95 case expInNumber: 96 buf = append(buf, it.buffer[it.head:i+1]...) 97 it.head = i + 1 98 return it.readFloat32ExponentPart(buf) 99 default: 100 buf = append(buf, it.buffer[it.head:i]...) 101 it.head = i 102 ret, err = it.parseFloat32(buf) 103 return ret, buf, err 104 } 105 } 106 } 107 // i == it.tail 108 buf = append(buf, it.buffer[it.head:i]...) 109 it.head = i 110 if err = it.readMore(); err != nil { 111 if err == io.EOF { 112 ret, err = it.parseFloat32(buf) 113 return ret, buf, err 114 } 115 return 0, buf, err 116 } 117 } 118 } 119 120 func (it *Iterator) readPositiveFloat32(c byte, buf []byte) (ret float32, _ []byte, err error) { 121 u := intDigits[c] 122 if u == invalidDigit { 123 return 0, buf, InvalidFloatError{c: c} 124 } 125 126 buf = append(buf, c) 127 if u == 0 { 128 if it.head == it.tail { 129 if err = it.readMore(); err != nil { 130 if err == io.EOF { 131 return 0, buf, nil 132 } 133 return 0, buf, err 134 } 135 } 136 switch floatDigits[it.buffer[it.head]] { 137 case dotInNumber: 138 it.head++ 139 buf = append(buf, '.') 140 return it.readFloat32FractionPart(buf) 141 case expInNumber: 142 it.head++ 143 buf = append(buf, 'e') 144 return it.readFloat32ExponentPart(buf) 145 default: 146 return 0, buf, nil 147 } 148 } else { 149 for { 150 i := it.head 151 for ; i < it.tail; i++ { 152 c = it.buffer[i] 153 digit := floatDigits[c] 154 if digit < 0 { 155 switch digit { 156 case dotInNumber: 157 buf = append(buf, it.buffer[it.head:i+1]...) 158 it.head = i + 1 159 return it.readFloat32FractionPart(buf) 160 case expInNumber: 161 buf = append(buf, it.buffer[it.head:i+1]...) 162 it.head = i + 1 163 return it.readFloat32ExponentPart(buf) 164 default: 165 buf = append(buf, it.buffer[it.head:i]...) 166 it.head = i 167 ret, err = it.parseFloat32(buf) 168 return ret, buf, err 169 } 170 } 171 } 172 // i == it.tail 173 buf = append(buf, it.buffer[it.head:i]...) 174 it.head = i 175 if err = it.readMore(); err != nil { 176 if err == io.EOF { 177 ret, err = it.parseFloat32(buf) 178 return ret, buf, err 179 } 180 return 0, buf, err 181 } 182 } 183 } 184 }