1package jsoniter
2
3import (
4	"math"
5	"strconv"
6)
7
8var intDigits []int8
9
10const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1
11const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1
12
13func init() {
14	intDigits = make([]int8, 256)
15	for i := 0; i < len(intDigits); i++ {
16		intDigits[i] = invalidCharForNumber
17	}
18	for i := int8('0'); i <= int8('9'); i++ {
19		intDigits[i] = i - int8('0')
20	}
21}
22
23// ReadUint read uint
24func (iter *Iterator) ReadUint() uint {
25	if strconv.IntSize == 32 {
26		return uint(iter.ReadUint32())
27	}
28	return uint(iter.ReadUint64())
29}
30
31// ReadInt read int
32func (iter *Iterator) ReadInt() int {
33	if strconv.IntSize == 32 {
34		return int(iter.ReadInt32())
35	}
36	return int(iter.ReadInt64())
37}
38
39// ReadInt8 read int8
40func (iter *Iterator) ReadInt8() (ret int8) {
41	c := iter.nextToken()
42	if c == '-' {
43		val := iter.readUint32(iter.readByte())
44		if val > math.MaxInt8+1 {
45			iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
46			return
47		}
48		return -int8(val)
49	}
50	val := iter.readUint32(c)
51	if val > math.MaxInt8 {
52		iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
53		return
54	}
55	return int8(val)
56}
57
58// ReadUint8 read uint8
59func (iter *Iterator) ReadUint8() (ret uint8) {
60	val := iter.readUint32(iter.nextToken())
61	if val > math.MaxUint8 {
62		iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10))
63		return
64	}
65	return uint8(val)
66}
67
68// ReadInt16 read int16
69func (iter *Iterator) ReadInt16() (ret int16) {
70	c := iter.nextToken()
71	if c == '-' {
72		val := iter.readUint32(iter.readByte())
73		if val > math.MaxInt16+1 {
74			iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
75			return
76		}
77		return -int16(val)
78	}
79	val := iter.readUint32(c)
80	if val > math.MaxInt16 {
81		iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
82		return
83	}
84	return int16(val)
85}
86
87// ReadUint16 read uint16
88func (iter *Iterator) ReadUint16() (ret uint16) {
89	val := iter.readUint32(iter.nextToken())
90	if val > math.MaxUint16 {
91		iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10))
92		return
93	}
94	return uint16(val)
95}
96
97// ReadInt32 read int32
98func (iter *Iterator) ReadInt32() (ret int32) {
99	c := iter.nextToken()
100	if c == '-' {
101		val := iter.readUint32(iter.readByte())
102		if val > math.MaxInt32+1 {
103			iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
104			return
105		}
106		return -int32(val)
107	}
108	val := iter.readUint32(c)
109	if val > math.MaxInt32 {
110		iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
111		return
112	}
113	return int32(val)
114}
115
116// ReadUint32 read uint32
117func (iter *Iterator) ReadUint32() (ret uint32) {
118	return iter.readUint32(iter.nextToken())
119}
120
121func (iter *Iterator) readUint32(c byte) (ret uint32) {
122	ind := intDigits[c]
123	if ind == 0 {
124		iter.assertInteger()
125		return 0 // single zero
126	}
127	if ind == invalidCharForNumber {
128		iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)}))
129		return
130	}
131	value := uint32(ind)
132	if iter.tail-iter.head > 10 {
133		i := iter.head
134		ind2 := intDigits[iter.buf[i]]
135		if ind2 == invalidCharForNumber {
136			iter.head = i
137			iter.assertInteger()
138			return value
139		}
140		i++
141		ind3 := intDigits[iter.buf[i]]
142		if ind3 == invalidCharForNumber {
143			iter.head = i
144			iter.assertInteger()
145			return value*10 + uint32(ind2)
146		}
147		//iter.head = i + 1
148		//value = value * 100 + uint32(ind2) * 10 + uint32(ind3)
149		i++
150		ind4 := intDigits[iter.buf[i]]
151		if ind4 == invalidCharForNumber {
152			iter.head = i
153			iter.assertInteger()
154			return value*100 + uint32(ind2)*10 + uint32(ind3)
155		}
156		i++
157		ind5 := intDigits[iter.buf[i]]
158		if ind5 == invalidCharForNumber {
159			iter.head = i
160			iter.assertInteger()
161			return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4)
162		}
163		i++
164		ind6 := intDigits[iter.buf[i]]
165		if ind6 == invalidCharForNumber {
166			iter.head = i
167			iter.assertInteger()
168			return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5)
169		}
170		i++
171		ind7 := intDigits[iter.buf[i]]
172		if ind7 == invalidCharForNumber {
173			iter.head = i
174			iter.assertInteger()
175			return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6)
176		}
177		i++
178		ind8 := intDigits[iter.buf[i]]
179		if ind8 == invalidCharForNumber {
180			iter.head = i
181			iter.assertInteger()
182			return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7)
183		}
184		i++
185		ind9 := intDigits[iter.buf[i]]
186		value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8)
187		iter.head = i
188		if ind9 == invalidCharForNumber {
189			iter.assertInteger()
190			return value
191		}
192	}
193	for {
194		for i := iter.head; i < iter.tail; i++ {
195			ind = intDigits[iter.buf[i]]
196			if ind == invalidCharForNumber {
197				iter.head = i
198				iter.assertInteger()
199				return value
200			}
201			if value > uint32SafeToMultiply10 {
202				value2 := (value << 3) + (value << 1) + uint32(ind)
203				if value2 < value {
204					iter.ReportError("readUint32", "overflow")
205					return
206				}
207				value = value2
208				continue
209			}
210			value = (value << 3) + (value << 1) + uint32(ind)
211		}
212		if !iter.loadMore() {
213			iter.assertInteger()
214			return value
215		}
216	}
217}
218
219// ReadInt64 read int64
220func (iter *Iterator) ReadInt64() (ret int64) {
221	c := iter.nextToken()
222	if c == '-' {
223		val := iter.readUint64(iter.readByte())
224		if val > math.MaxInt64+1 {
225			iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
226			return
227		}
228		return -int64(val)
229	}
230	val := iter.readUint64(c)
231	if val > math.MaxInt64 {
232		iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
233		return
234	}
235	return int64(val)
236}
237
238// ReadUint64 read uint64
239func (iter *Iterator) ReadUint64() uint64 {
240	return iter.readUint64(iter.nextToken())
241}
242
243func (iter *Iterator) readUint64(c byte) (ret uint64) {
244	ind := intDigits[c]
245	if ind == 0 {
246		iter.assertInteger()
247		return 0 // single zero
248	}
249	if ind == invalidCharForNumber {
250		iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)}))
251		return
252	}
253	value := uint64(ind)
254	if iter.tail-iter.head > 10 {
255		i := iter.head
256		ind2 := intDigits[iter.buf[i]]
257		if ind2 == invalidCharForNumber {
258			iter.head = i
259			iter.assertInteger()
260			return value
261		}
262		i++
263		ind3 := intDigits[iter.buf[i]]
264		if ind3 == invalidCharForNumber {
265			iter.head = i
266			iter.assertInteger()
267			return value*10 + uint64(ind2)
268		}
269		//iter.head = i + 1
270		//value = value * 100 + uint32(ind2) * 10 + uint32(ind3)
271		i++
272		ind4 := intDigits[iter.buf[i]]
273		if ind4 == invalidCharForNumber {
274			iter.head = i
275			iter.assertInteger()
276			return value*100 + uint64(ind2)*10 + uint64(ind3)
277		}
278		i++
279		ind5 := intDigits[iter.buf[i]]
280		if ind5 == invalidCharForNumber {
281			iter.head = i
282			iter.assertInteger()
283			return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4)
284		}
285		i++
286		ind6 := intDigits[iter.buf[i]]
287		if ind6 == invalidCharForNumber {
288			iter.head = i
289			iter.assertInteger()
290			return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5)
291		}
292		i++
293		ind7 := intDigits[iter.buf[i]]
294		if ind7 == invalidCharForNumber {
295			iter.head = i
296			iter.assertInteger()
297			return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6)
298		}
299		i++
300		ind8 := intDigits[iter.buf[i]]
301		if ind8 == invalidCharForNumber {
302			iter.head = i
303			iter.assertInteger()
304			return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7)
305		}
306		i++
307		ind9 := intDigits[iter.buf[i]]
308		value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8)
309		iter.head = i
310		if ind9 == invalidCharForNumber {
311			iter.assertInteger()
312			return value
313		}
314	}
315	for {
316		for i := iter.head; i < iter.tail; i++ {
317			ind = intDigits[iter.buf[i]]
318			if ind == invalidCharForNumber {
319				iter.head = i
320				iter.assertInteger()
321				return value
322			}
323			if value > uint64SafeToMultiple10 {
324				value2 := (value << 3) + (value << 1) + uint64(ind)
325				if value2 < value {
326					iter.ReportError("readUint64", "overflow")
327					return
328				}
329				value = value2
330				continue
331			}
332			value = (value << 3) + (value << 1) + uint64(ind)
333		}
334		if !iter.loadMore() {
335			iter.assertInteger()
336			return value
337		}
338	}
339}
340
341func (iter *Iterator) assertInteger() {
342	if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' {
343		iter.ReportError("assertInteger", "can not decode float as int")
344	}
345}
346