1
2
3
4
5 package json
6
7 import (
8 "math"
9 "strconv"
10 )
11
12
13
14 const (
15 maxInt64 = math.MaxInt64
16 minInt64 = math.MinInt64
17 maxUint64 = math.MaxUint64
18 minUint64 = 0
19
20 invalidTokenPanic = "invalid json.Token; it has been voided by a subsequent json.Decoder call"
21 )
22
23
24
25
26
27
28
29
30
31
32
33 type Token struct {
34 nonComparable
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 raw *decodeBuffer
72
73
74
75
76 str string
77
78
79
80 num uint64
81 }
82
83
84
85 var (
86 Null Token = rawToken("null")
87 False Token = rawToken("false")
88 True Token = rawToken("true")
89
90 ObjectStart Token = rawToken("{")
91 ObjectEnd Token = rawToken("}")
92 ArrayStart Token = rawToken("[")
93 ArrayEnd Token = rawToken("]")
94
95 zeroString Token = rawToken(`""`)
96 zeroNumber Token = rawToken(`0`)
97
98 nanString Token = String("NaN")
99 pinfString Token = String("Infinity")
100 ninfString Token = String("-Infinity")
101 )
102
103 func rawToken(s string) Token {
104 return Token{raw: &decodeBuffer{buf: []byte(s), prevStart: 0, prevEnd: len(s)}}
105 }
106
107
108 func Bool(b bool) Token {
109 if b {
110 return True
111 }
112 return False
113 }
114
115
116
117
118 func String(s string) Token {
119 if len(s) == 0 {
120 return zeroString
121 }
122 return Token{str: s}
123 }
124
125
126
127
128 func Float(n float64) Token {
129 switch {
130 case math.Float64bits(n) == 0:
131 return zeroNumber
132 case math.IsNaN(n):
133 return nanString
134 case math.IsInf(n, +1):
135 return pinfString
136 case math.IsInf(n, -1):
137 return ninfString
138 }
139 return Token{str: "f", num: math.Float64bits(n)}
140 }
141
142
143 func Int(n int64) Token {
144 if n == 0 {
145 return zeroNumber
146 }
147 return Token{str: "i", num: uint64(n)}
148 }
149
150
151 func Uint(n uint64) Token {
152 if n == 0 {
153 return zeroNumber
154 }
155 return Token{str: "u", num: uint64(n)}
156 }
157
158
159
160 func (t Token) Clone() Token {
161
162 if raw := t.raw; raw != nil {
163
164 if t.raw.prevStart == 0 {
165 switch t.raw {
166 case Null.raw:
167 return Null
168 case False.raw:
169 return False
170 case True.raw:
171 return True
172 case ObjectStart.raw:
173 return ObjectStart
174 case ObjectEnd.raw:
175 return ObjectEnd
176 case ArrayStart.raw:
177 return ArrayStart
178 case ArrayEnd.raw:
179 return ArrayEnd
180 }
181 }
182
183 if uint64(raw.previousOffsetStart()) != t.num {
184 panic(invalidTokenPanic)
185 }
186
187 buf := append([]byte(nil), raw.previousBuffer()...)
188 return Token{raw: &decodeBuffer{buf: buf, prevStart: 0, prevEnd: len(buf)}}
189 }
190 return t
191 }
192
193
194
195 func (t Token) Bool() bool {
196 switch t.raw {
197 case True.raw:
198 return true
199 case False.raw:
200 return false
201 default:
202 panic("invalid JSON token kind: " + t.Kind().String())
203 }
204 }
205
206
207
208 func (t Token) appendString(dst []byte, validateUTF8, preserveRaw bool, escapeRune func(rune) bool) ([]byte, error) {
209 if raw := t.raw; raw != nil {
210
211 buf := raw.previousBuffer()
212 if Kind(buf[0]) == '"' {
213 if escapeRune == nil && consumeSimpleString(buf) == len(buf) {
214 return append(dst, buf...), nil
215 }
216 dst, _, err := reformatString(dst, buf, validateUTF8, preserveRaw, escapeRune)
217 return dst, err
218 }
219 } else if len(t.str) != 0 && t.num == 0 {
220
221 return appendString(dst, t.str, validateUTF8, escapeRune)
222 }
223
224 panic("invalid JSON token kind: " + t.Kind().String())
225 }
226
227
228
229 func (t Token) String() string {
230
231
232
233
234 s, b := t.string()
235 if len(b) > 0 {
236 return string(b)
237 }
238 return s
239 }
240 func (t Token) string() (string, []byte) {
241 if raw := t.raw; raw != nil {
242 if uint64(raw.previousOffsetStart()) != t.num {
243 panic(invalidTokenPanic)
244 }
245 buf := raw.previousBuffer()
246 if buf[0] == '"' {
247
248 isVerbatim := consumeSimpleString(buf) == len(buf)
249 return "", unescapeStringMayCopy(buf, isVerbatim)
250 }
251
252 return "", buf
253 }
254 if len(t.str) != 0 && t.num == 0 {
255 return t.str, nil
256 }
257
258 if t.num > 0 {
259 switch t.str[0] {
260 case 'f':
261 return string(appendNumber(nil, math.Float64frombits(t.num), 64)), nil
262 case 'i':
263 return strconv.FormatInt(int64(t.num), 10), nil
264 case 'u':
265 return strconv.FormatUint(uint64(t.num), 10), nil
266 }
267 }
268 return "<invalid json.Token>", nil
269 }
270
271
272
273 func (t Token) appendNumber(dst []byte, canonicalize bool) ([]byte, error) {
274 if raw := t.raw; raw != nil {
275
276 buf := raw.previousBuffer()
277 if Kind(buf[0]).normalize() == '0' {
278 if !canonicalize {
279 return append(dst, buf...), nil
280 }
281 dst, _, err := reformatNumber(dst, buf, canonicalize)
282 return dst, err
283 }
284 } else if t.num != 0 {
285
286 switch t.str[0] {
287 case 'f':
288 return appendNumber(dst, math.Float64frombits(t.num), 64), nil
289 case 'i':
290 return strconv.AppendInt(dst, int64(t.num), 10), nil
291 case 'u':
292 return strconv.AppendUint(dst, uint64(t.num), 10), nil
293 }
294 }
295
296 panic("invalid JSON token kind: " + t.Kind().String())
297 }
298
299
300
301
302
303 func (t Token) Float() float64 {
304 if raw := t.raw; raw != nil {
305
306 if uint64(raw.previousOffsetStart()) != t.num {
307 panic(invalidTokenPanic)
308 }
309 buf := raw.previousBuffer()
310 if Kind(buf[0]).normalize() == '0' {
311 fv, _ := parseFloat(buf, 64)
312 return fv
313 }
314 } else if t.num != 0 {
315
316 switch t.str[0] {
317 case 'f':
318 return math.Float64frombits(t.num)
319 case 'i':
320 return float64(int64(t.num))
321 case 'u':
322 return float64(uint64(t.num))
323 }
324 }
325
326
327 if t.Kind() == '"' {
328 switch t.String() {
329 case "NaN":
330 return math.NaN()
331 case "Infinity":
332 return math.Inf(+1)
333 case "-Infinity":
334 return math.Inf(-1)
335 }
336 }
337
338 panic("invalid JSON token kind: " + t.Kind().String())
339 }
340
341
342
343
344
345
346 func (t Token) Int() int64 {
347 if raw := t.raw; raw != nil {
348
349 if uint64(raw.previousOffsetStart()) != t.num {
350 panic(invalidTokenPanic)
351 }
352 neg := false
353 buf := raw.previousBuffer()
354 if len(buf) > 0 && buf[0] == '-' {
355 neg, buf = true, buf[1:]
356 }
357 if numAbs, ok := parseDecUint(buf); ok {
358 if neg {
359 if numAbs > -minInt64 {
360 return minInt64
361 }
362 return -1 * int64(numAbs)
363 } else {
364 if numAbs > +maxInt64 {
365 return maxInt64
366 }
367 return +1 * int64(numAbs)
368 }
369 }
370 } else if t.num != 0 {
371
372 switch t.str[0] {
373 case 'i':
374 return int64(t.num)
375 case 'u':
376 if t.num > maxInt64 {
377 return maxInt64
378 }
379 return int64(t.num)
380 }
381 }
382
383
384 if t.Kind() == '0' {
385 switch fv := t.Float(); {
386 case fv >= maxInt64:
387 return maxInt64
388 case fv <= minInt64:
389 return minInt64
390 default:
391 return int64(fv)
392 }
393 }
394
395 panic("invalid JSON token kind: " + t.Kind().String())
396 }
397
398
399
400
401
402
403 func (t Token) Uint() uint64 {
404
405
406
407
408 if raw := t.raw; raw != nil {
409
410 if uint64(raw.previousOffsetStart()) != t.num {
411 panic(invalidTokenPanic)
412 }
413 neg := false
414 buf := raw.previousBuffer()
415 if len(buf) > 0 && buf[0] == '-' {
416 neg, buf = true, buf[1:]
417 }
418 if num, ok := parseDecUint(buf); ok {
419 if neg {
420 return minUint64
421 }
422 return num
423 }
424 } else if t.num != 0 {
425
426 switch t.str[0] {
427 case 'u':
428 return t.num
429 case 'i':
430 if int64(t.num) < minUint64 {
431 return minUint64
432 }
433 return uint64(int64(t.num))
434 }
435 }
436
437
438 if t.Kind() == '0' {
439 switch fv := t.Float(); {
440 case fv >= maxUint64:
441 return maxUint64
442 case fv <= minUint64:
443 return minUint64
444 default:
445 return uint64(fv)
446 }
447 }
448
449 panic("invalid JSON token kind: " + t.Kind().String())
450 }
451
452
453 func (t Token) Kind() Kind {
454 switch {
455 case t.raw != nil:
456 raw := t.raw
457 if uint64(raw.previousOffsetStart()) != t.num {
458 panic(invalidTokenPanic)
459 }
460 return Kind(t.raw.buf[raw.prevStart]).normalize()
461 case t.num != 0:
462 return '0'
463 case len(t.str) != 0:
464 return '"'
465 default:
466 return invalidKind
467 }
468 }
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486 type Kind byte
487
488 const invalidKind Kind = 0
489
490
491 func (k Kind) String() string {
492 switch k {
493 case 'n':
494 return "null"
495 case 'f':
496 return "false"
497 case 't':
498 return "true"
499 case '"':
500 return "string"
501 case '0':
502 return "number"
503 case '{':
504 return "{"
505 case '}':
506 return "}"
507 case '[':
508 return "["
509 case ']':
510 return "]"
511 default:
512 return "<invalid json.Kind: " + quoteRune([]byte{byte(k)}) + ">"
513 }
514 }
515
516
517 func (k Kind) normalize() Kind {
518 if k == '-' || ('0' <= k && k <= '9') {
519 return '0'
520 }
521 return k
522 }
523
View as plain text