diff options
author | Rutger Broekhoff | 2023-12-29 21:31:53 +0100 |
---|---|---|
committer | Rutger Broekhoff | 2023-12-29 21:31:53 +0100 |
commit | 404aeae4545d2426c089a5f8d5e82dae56f5212b (patch) | |
tree | 2d84e00af272b39fc04f3795ae06bc48970e57b5 /vendor/github.com/json-iterator/go/iter_float.go | |
parent | 209d8b0187ed025dec9ac149ebcced3462877bff (diff) | |
download | gitolfs3-404aeae4545d2426c089a5f8d5e82dae56f5212b.tar.gz gitolfs3-404aeae4545d2426c089a5f8d5e82dae56f5212b.zip |
Make Nix builds work
Diffstat (limited to 'vendor/github.com/json-iterator/go/iter_float.go')
-rw-r--r-- | vendor/github.com/json-iterator/go/iter_float.go | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/vendor/github.com/json-iterator/go/iter_float.go b/vendor/github.com/json-iterator/go/iter_float.go new file mode 100644 index 0000000..8a3d8b6 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_float.go | |||
@@ -0,0 +1,342 @@ | |||
1 | package jsoniter | ||
2 | |||
3 | import ( | ||
4 | "encoding/json" | ||
5 | "io" | ||
6 | "math/big" | ||
7 | "strconv" | ||
8 | "strings" | ||
9 | "unsafe" | ||
10 | ) | ||
11 | |||
12 | var floatDigits []int8 | ||
13 | |||
14 | const invalidCharForNumber = int8(-1) | ||
15 | const endOfNumber = int8(-2) | ||
16 | const dotInNumber = int8(-3) | ||
17 | |||
18 | func init() { | ||
19 | floatDigits = make([]int8, 256) | ||
20 | for i := 0; i < len(floatDigits); i++ { | ||
21 | floatDigits[i] = invalidCharForNumber | ||
22 | } | ||
23 | for i := int8('0'); i <= int8('9'); i++ { | ||
24 | floatDigits[i] = i - int8('0') | ||
25 | } | ||
26 | floatDigits[','] = endOfNumber | ||
27 | floatDigits[']'] = endOfNumber | ||
28 | floatDigits['}'] = endOfNumber | ||
29 | floatDigits[' '] = endOfNumber | ||
30 | floatDigits['\t'] = endOfNumber | ||
31 | floatDigits['\n'] = endOfNumber | ||
32 | floatDigits['.'] = dotInNumber | ||
33 | } | ||
34 | |||
35 | // ReadBigFloat read big.Float | ||
36 | func (iter *Iterator) ReadBigFloat() (ret *big.Float) { | ||
37 | str := iter.readNumberAsString() | ||
38 | if iter.Error != nil && iter.Error != io.EOF { | ||
39 | return nil | ||
40 | } | ||
41 | prec := 64 | ||
42 | if len(str) > prec { | ||
43 | prec = len(str) | ||
44 | } | ||
45 | val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero) | ||
46 | if err != nil { | ||
47 | iter.Error = err | ||
48 | return nil | ||
49 | } | ||
50 | return val | ||
51 | } | ||
52 | |||
53 | // ReadBigInt read big.Int | ||
54 | func (iter *Iterator) ReadBigInt() (ret *big.Int) { | ||
55 | str := iter.readNumberAsString() | ||
56 | if iter.Error != nil && iter.Error != io.EOF { | ||
57 | return nil | ||
58 | } | ||
59 | ret = big.NewInt(0) | ||
60 | var success bool | ||
61 | ret, success = ret.SetString(str, 10) | ||
62 | if !success { | ||
63 | iter.ReportError("ReadBigInt", "invalid big int") | ||
64 | return nil | ||
65 | } | ||
66 | return ret | ||
67 | } | ||
68 | |||
69 | //ReadFloat32 read float32 | ||
70 | func (iter *Iterator) ReadFloat32() (ret float32) { | ||
71 | c := iter.nextToken() | ||
72 | if c == '-' { | ||
73 | return -iter.readPositiveFloat32() | ||
74 | } | ||
75 | iter.unreadByte() | ||
76 | return iter.readPositiveFloat32() | ||
77 | } | ||
78 | |||
79 | func (iter *Iterator) readPositiveFloat32() (ret float32) { | ||
80 | i := iter.head | ||
81 | // first char | ||
82 | if i == iter.tail { | ||
83 | return iter.readFloat32SlowPath() | ||
84 | } | ||
85 | c := iter.buf[i] | ||
86 | i++ | ||
87 | ind := floatDigits[c] | ||
88 | switch ind { | ||
89 | case invalidCharForNumber: | ||
90 | return iter.readFloat32SlowPath() | ||
91 | case endOfNumber: | ||
92 | iter.ReportError("readFloat32", "empty number") | ||
93 | return | ||
94 | case dotInNumber: | ||
95 | iter.ReportError("readFloat32", "leading dot is invalid") | ||
96 | return | ||
97 | case 0: | ||
98 | if i == iter.tail { | ||
99 | return iter.readFloat32SlowPath() | ||
100 | } | ||
101 | c = iter.buf[i] | ||
102 | switch c { | ||
103 | case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': | ||
104 | iter.ReportError("readFloat32", "leading zero is invalid") | ||
105 | return | ||
106 | } | ||
107 | } | ||
108 | value := uint64(ind) | ||
109 | // chars before dot | ||
110 | non_decimal_loop: | ||
111 | for ; i < iter.tail; i++ { | ||
112 | c = iter.buf[i] | ||
113 | ind := floatDigits[c] | ||
114 | switch ind { | ||
115 | case invalidCharForNumber: | ||
116 | return iter.readFloat32SlowPath() | ||
117 | case endOfNumber: | ||
118 | iter.head = i | ||
119 | return float32(value) | ||
120 | case dotInNumber: | ||
121 | break non_decimal_loop | ||
122 | } | ||
123 | if value > uint64SafeToMultiple10 { | ||
124 | return iter.readFloat32SlowPath() | ||
125 | } | ||
126 | value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; | ||
127 | } | ||
128 | // chars after dot | ||
129 | if c == '.' { | ||
130 | i++ | ||
131 | decimalPlaces := 0 | ||
132 | if i == iter.tail { | ||
133 | return iter.readFloat32SlowPath() | ||
134 | } | ||
135 | for ; i < iter.tail; i++ { | ||
136 | c = iter.buf[i] | ||
137 | ind := floatDigits[c] | ||
138 | switch ind { | ||
139 | case endOfNumber: | ||
140 | if decimalPlaces > 0 && decimalPlaces < len(pow10) { | ||
141 | iter.head = i | ||
142 | return float32(float64(value) / float64(pow10[decimalPlaces])) | ||
143 | } | ||
144 | // too many decimal places | ||
145 | return iter.readFloat32SlowPath() | ||
146 | case invalidCharForNumber, dotInNumber: | ||
147 | return iter.readFloat32SlowPath() | ||
148 | } | ||
149 | decimalPlaces++ | ||
150 | if value > uint64SafeToMultiple10 { | ||
151 | return iter.readFloat32SlowPath() | ||
152 | } | ||
153 | value = (value << 3) + (value << 1) + uint64(ind) | ||
154 | } | ||
155 | } | ||
156 | return iter.readFloat32SlowPath() | ||
157 | } | ||
158 | |||
159 | func (iter *Iterator) readNumberAsString() (ret string) { | ||
160 | strBuf := [16]byte{} | ||
161 | str := strBuf[0:0] | ||
162 | load_loop: | ||
163 | for { | ||
164 | for i := iter.head; i < iter.tail; i++ { | ||
165 | c := iter.buf[i] | ||
166 | switch c { | ||
167 | case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': | ||
168 | str = append(str, c) | ||
169 | continue | ||
170 | default: | ||
171 | iter.head = i | ||
172 | break load_loop | ||
173 | } | ||
174 | } | ||
175 | if !iter.loadMore() { | ||
176 | break | ||
177 | } | ||
178 | } | ||
179 | if iter.Error != nil && iter.Error != io.EOF { | ||
180 | return | ||
181 | } | ||
182 | if len(str) == 0 { | ||
183 | iter.ReportError("readNumberAsString", "invalid number") | ||
184 | } | ||
185 | return *(*string)(unsafe.Pointer(&str)) | ||
186 | } | ||
187 | |||
188 | func (iter *Iterator) readFloat32SlowPath() (ret float32) { | ||
189 | str := iter.readNumberAsString() | ||
190 | if iter.Error != nil && iter.Error != io.EOF { | ||
191 | return | ||
192 | } | ||
193 | errMsg := validateFloat(str) | ||
194 | if errMsg != "" { | ||
195 | iter.ReportError("readFloat32SlowPath", errMsg) | ||
196 | return | ||
197 | } | ||
198 | val, err := strconv.ParseFloat(str, 32) | ||
199 | if err != nil { | ||
200 | iter.Error = err | ||
201 | return | ||
202 | } | ||
203 | return float32(val) | ||
204 | } | ||
205 | |||
206 | // ReadFloat64 read float64 | ||
207 | func (iter *Iterator) ReadFloat64() (ret float64) { | ||
208 | c := iter.nextToken() | ||
209 | if c == '-' { | ||
210 | return -iter.readPositiveFloat64() | ||
211 | } | ||
212 | iter.unreadByte() | ||
213 | return iter.readPositiveFloat64() | ||
214 | } | ||
215 | |||
216 | func (iter *Iterator) readPositiveFloat64() (ret float64) { | ||
217 | i := iter.head | ||
218 | // first char | ||
219 | if i == iter.tail { | ||
220 | return iter.readFloat64SlowPath() | ||
221 | } | ||
222 | c := iter.buf[i] | ||
223 | i++ | ||
224 | ind := floatDigits[c] | ||
225 | switch ind { | ||
226 | case invalidCharForNumber: | ||
227 | return iter.readFloat64SlowPath() | ||
228 | case endOfNumber: | ||
229 | iter.ReportError("readFloat64", "empty number") | ||
230 | return | ||
231 | case dotInNumber: | ||
232 | iter.ReportError("readFloat64", "leading dot is invalid") | ||
233 | return | ||
234 | case 0: | ||
235 | if i == iter.tail { | ||
236 | return iter.readFloat64SlowPath() | ||
237 | } | ||
238 | c = iter.buf[i] | ||
239 | switch c { | ||
240 | case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': | ||
241 | iter.ReportError("readFloat64", "leading zero is invalid") | ||
242 | return | ||
243 | } | ||
244 | } | ||
245 | value := uint64(ind) | ||
246 | // chars before dot | ||
247 | non_decimal_loop: | ||
248 | for ; i < iter.tail; i++ { | ||
249 | c = iter.buf[i] | ||
250 | ind := floatDigits[c] | ||
251 | switch ind { | ||
252 | case invalidCharForNumber: | ||
253 | return iter.readFloat64SlowPath() | ||
254 | case endOfNumber: | ||
255 | iter.head = i | ||
256 | return float64(value) | ||
257 | case dotInNumber: | ||
258 | break non_decimal_loop | ||
259 | } | ||
260 | if value > uint64SafeToMultiple10 { | ||
261 | return iter.readFloat64SlowPath() | ||
262 | } | ||
263 | value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; | ||
264 | } | ||
265 | // chars after dot | ||
266 | if c == '.' { | ||
267 | i++ | ||
268 | decimalPlaces := 0 | ||
269 | if i == iter.tail { | ||
270 | return iter.readFloat64SlowPath() | ||
271 | } | ||
272 | for ; i < iter.tail; i++ { | ||
273 | c = iter.buf[i] | ||
274 | ind := floatDigits[c] | ||
275 | switch ind { | ||
276 | case endOfNumber: | ||
277 | if decimalPlaces > 0 && decimalPlaces < len(pow10) { | ||
278 | iter.head = i | ||
279 | return float64(value) / float64(pow10[decimalPlaces]) | ||
280 | } | ||
281 | // too many decimal places | ||
282 | return iter.readFloat64SlowPath() | ||
283 | case invalidCharForNumber, dotInNumber: | ||
284 | return iter.readFloat64SlowPath() | ||
285 | } | ||
286 | decimalPlaces++ | ||
287 | if value > uint64SafeToMultiple10 { | ||
288 | return iter.readFloat64SlowPath() | ||
289 | } | ||
290 | value = (value << 3) + (value << 1) + uint64(ind) | ||
291 | if value > maxFloat64 { | ||
292 | return iter.readFloat64SlowPath() | ||
293 | } | ||
294 | } | ||
295 | } | ||
296 | return iter.readFloat64SlowPath() | ||
297 | } | ||
298 | |||
299 | func (iter *Iterator) readFloat64SlowPath() (ret float64) { | ||
300 | str := iter.readNumberAsString() | ||
301 | if iter.Error != nil && iter.Error != io.EOF { | ||
302 | return | ||
303 | } | ||
304 | errMsg := validateFloat(str) | ||
305 | if errMsg != "" { | ||
306 | iter.ReportError("readFloat64SlowPath", errMsg) | ||
307 | return | ||
308 | } | ||
309 | val, err := strconv.ParseFloat(str, 64) | ||
310 | if err != nil { | ||
311 | iter.Error = err | ||
312 | return | ||
313 | } | ||
314 | return val | ||
315 | } | ||
316 | |||
317 | func validateFloat(str string) string { | ||
318 | // strconv.ParseFloat is not validating `1.` or `1.e1` | ||
319 | if len(str) == 0 { | ||
320 | return "empty number" | ||
321 | } | ||
322 | if str[0] == '-' { | ||
323 | return "-- is not valid" | ||
324 | } | ||
325 | dotPos := strings.IndexByte(str, '.') | ||
326 | if dotPos != -1 { | ||
327 | if dotPos == len(str)-1 { | ||
328 | return "dot can not be last character" | ||
329 | } | ||
330 | switch str[dotPos+1] { | ||
331 | case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': | ||
332 | default: | ||
333 | return "missing digit after dot" | ||
334 | } | ||
335 | } | ||
336 | return "" | ||
337 | } | ||
338 | |||
339 | // ReadNumber read json.Number | ||
340 | func (iter *Iterator) ReadNumber() (ret json.Number) { | ||
341 | return json.Number(iter.readNumberAsString()) | ||
342 | } | ||