OSDN Git Service

feat(warder): add warder backbone (#181)
[bytom/vapor.git] / vendor / github.com / ugorji / go / codec / json.go
1 // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
2 // Use of this source code is governed by a MIT license found in the LICENSE file.
3
4 package codec
5
6 // By default, this json support uses base64 encoding for bytes, because you cannot
7 // store and read any arbitrary string in json (only unicode).
8 // However, the user can configre how to encode/decode bytes.
9 //
10 // This library specifically supports UTF-8 for encoding and decoding only.
11 //
12 // Note that the library will happily encode/decode things which are not valid
13 // json e.g. a map[int64]string. We do it for consistency. With valid json,
14 // we will encode and decode appropriately.
15 // Users can specify their map type if necessary to force it.
16 //
17 // Note:
18 //   - we cannot use strconv.Quote and strconv.Unquote because json quotes/unquotes differently.
19 //     We implement it here.
20
21 // Top-level methods of json(End|Dec)Driver (which are implementations of (en|de)cDriver
22 // MUST not call one-another.
23
24 import (
25         "bytes"
26         "encoding/base64"
27         "math"
28         "reflect"
29         "strconv"
30         "time"
31         "unicode"
32         "unicode/utf16"
33         "unicode/utf8"
34 )
35
36 //--------------------------------
37
38 var jsonLiterals = [...]byte{
39         '"', 't', 'r', 'u', 'e', '"',
40         '"', 'f', 'a', 'l', 's', 'e', '"',
41         '"', 'n', 'u', 'l', 'l', '"',
42 }
43
44 const (
45         jsonLitTrueQ  = 0
46         jsonLitTrue   = 1
47         jsonLitFalseQ = 6
48         jsonLitFalse  = 7
49         jsonLitNullQ  = 13
50         jsonLitNull   = 14
51 )
52
53 const (
54         jsonU4Chk2 = '0'
55         jsonU4Chk1 = 'a' - 10
56         jsonU4Chk0 = 'A' - 10
57
58         jsonScratchArrayLen = 64
59 )
60
61 const (
62         // If !jsonValidateSymbols, decoding will be faster, by skipping some checks:
63         //   - If we see first character of null, false or true,
64         //     do not validate subsequent characters.
65         //   - e.g. if we see a n, assume null and skip next 3 characters,
66         //     and do not validate they are ull.
67         // P.S. Do not expect a significant decoding boost from this.
68         jsonValidateSymbols = true
69
70         jsonSpacesOrTabsLen = 128
71
72         jsonAlwaysReturnInternString = false
73 )
74
75 var (
76         // jsonTabs and jsonSpaces are used as caches for indents
77         jsonTabs, jsonSpaces [jsonSpacesOrTabsLen]byte
78
79         jsonCharHtmlSafeSet   bitset128
80         jsonCharSafeSet       bitset128
81         jsonCharWhitespaceSet bitset256
82         jsonNumSet            bitset256
83 )
84
85 func init() {
86         for i := 0; i < jsonSpacesOrTabsLen; i++ {
87                 jsonSpaces[i] = ' '
88                 jsonTabs[i] = '\t'
89         }
90
91         // populate the safe values as true: note: ASCII control characters are (0-31)
92         // jsonCharSafeSet:     all true except (0-31) " \
93         // jsonCharHtmlSafeSet: all true except (0-31) " \ < > &
94         var i byte
95         for i = 32; i < utf8.RuneSelf; i++ {
96                 switch i {
97                 case '"', '\\':
98                 case '<', '>', '&':
99                         jsonCharSafeSet.set(i) // = true
100                 default:
101                         jsonCharSafeSet.set(i)
102                         jsonCharHtmlSafeSet.set(i)
103                 }
104         }
105         for i = 0; i <= utf8.RuneSelf; i++ {
106                 switch i {
107                 case ' ', '\t', '\r', '\n':
108                         jsonCharWhitespaceSet.set(i)
109                 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-':
110                         jsonNumSet.set(i)
111                 }
112         }
113 }
114
115 // ----------------
116
117 type jsonEncDriverTypical struct {
118         w  encWriter
119         b  *[jsonScratchArrayLen]byte
120         tw bool // term white space
121         c  containerState
122 }
123
124 func (e *jsonEncDriverTypical) typical() {}
125
126 func (e *jsonEncDriverTypical) reset(ee *jsonEncDriver) {
127         e.w = ee.ew
128         e.b = &ee.b
129         e.tw = ee.h.TermWhitespace
130         e.c = 0
131 }
132
133 func (e *jsonEncDriverTypical) WriteArrayStart(length int) {
134         e.w.writen1('[')
135         e.c = containerArrayStart
136 }
137
138 func (e *jsonEncDriverTypical) WriteArrayElem() {
139         if e.c != containerArrayStart {
140                 e.w.writen1(',')
141         }
142         e.c = containerArrayElem
143 }
144
145 func (e *jsonEncDriverTypical) WriteArrayEnd() {
146         e.w.writen1(']')
147         e.c = containerArrayEnd
148 }
149
150 func (e *jsonEncDriverTypical) WriteMapStart(length int) {
151         e.w.writen1('{')
152         e.c = containerMapStart
153 }
154
155 func (e *jsonEncDriverTypical) WriteMapElemKey() {
156         if e.c != containerMapStart {
157                 e.w.writen1(',')
158         }
159         e.c = containerMapKey
160 }
161
162 func (e *jsonEncDriverTypical) WriteMapElemValue() {
163         e.w.writen1(':')
164         e.c = containerMapValue
165 }
166
167 func (e *jsonEncDriverTypical) WriteMapEnd() {
168         e.w.writen1('}')
169         e.c = containerMapEnd
170 }
171
172 func (e *jsonEncDriverTypical) EncodeBool(b bool) {
173         if b {
174                 e.w.writeb(jsonLiterals[jsonLitTrue : jsonLitTrue+4])
175         } else {
176                 e.w.writeb(jsonLiterals[jsonLitFalse : jsonLitFalse+5])
177         }
178 }
179
180 func (e *jsonEncDriverTypical) EncodeFloat64(f float64) {
181         fmt, prec := jsonFloatStrconvFmtPrec(f)
182         e.w.writeb(strconv.AppendFloat(e.b[:0], f, fmt, prec, 64))
183 }
184
185 func (e *jsonEncDriverTypical) EncodeInt(v int64) {
186         e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
187 }
188
189 func (e *jsonEncDriverTypical) EncodeUint(v uint64) {
190         e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
191 }
192
193 func (e *jsonEncDriverTypical) EncodeFloat32(f float32) {
194         e.EncodeFloat64(float64(f))
195 }
196
197 func (e *jsonEncDriverTypical) atEndOfEncode() {
198         if e.tw {
199                 e.w.writen1(' ')
200         }
201 }
202
203 // ----------------
204
205 type jsonEncDriverGeneric struct {
206         w encWriter
207         b *[jsonScratchArrayLen]byte
208         c containerState
209         // ds string // indent string
210         di int8    // indent per
211         d  bool    // indenting?
212         dt bool    // indent using tabs
213         dl uint16  // indent level
214         ks bool    // map key as string
215         is byte    // integer as string
216         tw bool    // term white space
217         _  [7]byte // padding
218 }
219
220 // indent is done as below:
221 //   - newline and indent are added before each mapKey or arrayElem
222 //   - newline and indent are added before each ending,
223 //     except there was no entry (so we can have {} or [])
224
225 func (e *jsonEncDriverGeneric) reset(ee *jsonEncDriver) {
226         e.w = ee.ew
227         e.b = &ee.b
228         e.tw = ee.h.TermWhitespace
229         e.c = 0
230         e.d, e.dt, e.dl, e.di = false, false, 0, 0
231         h := ee.h
232         if h.Indent > 0 {
233                 e.d = true
234                 e.di = int8(h.Indent)
235         } else if h.Indent < 0 {
236                 e.d = true
237                 e.dt = true
238                 e.di = int8(-h.Indent)
239         }
240         e.ks = h.MapKeyAsString
241         e.is = h.IntegerAsString
242 }
243
244 func (e *jsonEncDriverGeneric) WriteArrayStart(length int) {
245         if e.d {
246                 e.dl++
247         }
248         e.w.writen1('[')
249         e.c = containerArrayStart
250 }
251
252 func (e *jsonEncDriverGeneric) WriteArrayElem() {
253         if e.c != containerArrayStart {
254                 e.w.writen1(',')
255         }
256         if e.d {
257                 e.writeIndent()
258         }
259         e.c = containerArrayElem
260 }
261
262 func (e *jsonEncDriverGeneric) WriteArrayEnd() {
263         if e.d {
264                 e.dl--
265                 if e.c != containerArrayStart {
266                         e.writeIndent()
267                 }
268         }
269         e.w.writen1(']')
270         e.c = containerArrayEnd
271 }
272
273 func (e *jsonEncDriverGeneric) WriteMapStart(length int) {
274         if e.d {
275                 e.dl++
276         }
277         e.w.writen1('{')
278         e.c = containerMapStart
279 }
280
281 func (e *jsonEncDriverGeneric) WriteMapElemKey() {
282         if e.c != containerMapStart {
283                 e.w.writen1(',')
284         }
285         if e.d {
286                 e.writeIndent()
287         }
288         e.c = containerMapKey
289 }
290
291 func (e *jsonEncDriverGeneric) WriteMapElemValue() {
292         if e.d {
293                 e.w.writen2(':', ' ')
294         } else {
295                 e.w.writen1(':')
296         }
297         e.c = containerMapValue
298 }
299
300 func (e *jsonEncDriverGeneric) WriteMapEnd() {
301         if e.d {
302                 e.dl--
303                 if e.c != containerMapStart {
304                         e.writeIndent()
305                 }
306         }
307         e.w.writen1('}')
308         e.c = containerMapEnd
309 }
310
311 func (e *jsonEncDriverGeneric) writeIndent() {
312         e.w.writen1('\n')
313         x := int(e.di) * int(e.dl)
314         if e.dt {
315                 for x > jsonSpacesOrTabsLen {
316                         e.w.writeb(jsonTabs[:])
317                         x -= jsonSpacesOrTabsLen
318                 }
319                 e.w.writeb(jsonTabs[:x])
320         } else {
321                 for x > jsonSpacesOrTabsLen {
322                         e.w.writeb(jsonSpaces[:])
323                         x -= jsonSpacesOrTabsLen
324                 }
325                 e.w.writeb(jsonSpaces[:x])
326         }
327 }
328
329 func (e *jsonEncDriverGeneric) EncodeBool(b bool) {
330         if e.ks && e.c == containerMapKey {
331                 if b {
332                         e.w.writeb(jsonLiterals[jsonLitTrueQ : jsonLitTrueQ+6])
333                 } else {
334                         e.w.writeb(jsonLiterals[jsonLitFalseQ : jsonLitFalseQ+7])
335                 }
336         } else {
337                 if b {
338                         e.w.writeb(jsonLiterals[jsonLitTrue : jsonLitTrue+4])
339                 } else {
340                         e.w.writeb(jsonLiterals[jsonLitFalse : jsonLitFalse+5])
341                 }
342         }
343 }
344
345 func (e *jsonEncDriverGeneric) EncodeFloat64(f float64) {
346         // instead of using 'g', specify whether to use 'e' or 'f'
347         fmt, prec := jsonFloatStrconvFmtPrec(f)
348
349         var blen int
350         if e.ks && e.c == containerMapKey {
351                 blen = 2 + len(strconv.AppendFloat(e.b[1:1], f, fmt, prec, 64))
352                 e.b[0] = '"'
353                 e.b[blen-1] = '"'
354         } else {
355                 blen = len(strconv.AppendFloat(e.b[:0], f, fmt, prec, 64))
356         }
357         e.w.writeb(e.b[:blen])
358 }
359
360 func (e *jsonEncDriverGeneric) EncodeInt(v int64) {
361         x := e.is
362         if x == 'A' || x == 'L' && (v > 1<<53 || v < -(1<<53)) || (e.ks && e.c == containerMapKey) {
363                 blen := 2 + len(strconv.AppendInt(e.b[1:1], v, 10))
364                 e.b[0] = '"'
365                 e.b[blen-1] = '"'
366                 e.w.writeb(e.b[:blen])
367                 return
368         }
369         e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
370 }
371
372 func (e *jsonEncDriverGeneric) EncodeUint(v uint64) {
373         x := e.is
374         if x == 'A' || x == 'L' && v > 1<<53 || (e.ks && e.c == containerMapKey) {
375                 blen := 2 + len(strconv.AppendUint(e.b[1:1], v, 10))
376                 e.b[0] = '"'
377                 e.b[blen-1] = '"'
378                 e.w.writeb(e.b[:blen])
379                 return
380         }
381         e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
382 }
383
384 func (e *jsonEncDriverGeneric) EncodeFloat32(f float32) {
385         // e.encodeFloat(float64(f), 32)
386         // always encode all floats as IEEE 64-bit floating point.
387         // It also ensures that we can decode in full precision even if into a float32,
388         // as what is written is always to float64 precision.
389         e.EncodeFloat64(float64(f))
390 }
391
392 func (e *jsonEncDriverGeneric) atEndOfEncode() {
393         if e.tw {
394                 if e.d {
395                         e.w.writen1('\n')
396                 } else {
397                         e.w.writen1(' ')
398                 }
399         }
400 }
401
402 // --------------------
403
404 type jsonEncDriver struct {
405         noBuiltInTypes
406         e  *Encoder
407         h  *JsonHandle
408         ew encWriter
409         se extWrapper
410         // ---- cpu cache line boundary?
411         bs []byte // scratch
412         // ---- cpu cache line boundary?
413         b [jsonScratchArrayLen]byte // scratch (encode time,
414         _ [2]uint64                 // padding
415 }
416
417 func (e *jsonEncDriver) EncodeNil() {
418         // We always encode nil as just null (never in quotes)
419         // This allows us to easily decode if a nil in the json stream
420         // ie if initial token is n.
421         e.ew.writeb(jsonLiterals[jsonLitNull : jsonLitNull+4])
422
423         // if e.h.MapKeyAsString && e.c == containerMapKey {
424         //      e.ew.writeb(jsonLiterals[jsonLitNullQ : jsonLitNullQ+6])
425         // } else {
426         //      e.ew.writeb(jsonLiterals[jsonLitNull : jsonLitNull+4])
427         // }
428 }
429
430 func (e *jsonEncDriver) EncodeTime(t time.Time) {
431         // Do NOT use MarshalJSON, as it allocates internally.
432         // instead, we call AppendFormat directly, using our scratch buffer (e.b)
433         if t.IsZero() {
434                 e.EncodeNil()
435         } else {
436                 e.b[0] = '"'
437                 b := t.AppendFormat(e.b[1:1], time.RFC3339Nano)
438                 e.b[len(b)+1] = '"'
439                 e.ew.writeb(e.b[:len(b)+2])
440         }
441         // v, err := t.MarshalJSON(); if err != nil { e.e.error(err) } e.ew.writeb(v)
442 }
443
444 func (e *jsonEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
445         if v := ext.ConvertExt(rv); v == nil {
446                 e.EncodeNil()
447         } else {
448                 en.encode(v)
449         }
450 }
451
452 func (e *jsonEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
453         // only encodes re.Value (never re.Data)
454         if re.Value == nil {
455                 e.EncodeNil()
456         } else {
457                 en.encode(re.Value)
458         }
459 }
460
461 func (e *jsonEncDriver) EncodeString(c charEncoding, v string) {
462         e.quoteStr(v)
463 }
464
465 func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
466         // if encoding raw bytes and RawBytesExt is configured, use it to encode
467         if v == nil {
468                 e.EncodeNil()
469                 return
470         }
471         if c == cRAW {
472                 if e.se.InterfaceExt != nil {
473                         e.EncodeExt(v, 0, &e.se, e.e)
474                         return
475                 }
476
477                 slen := base64.StdEncoding.EncodedLen(len(v))
478                 if cap(e.bs) >= slen+2 {
479                         e.bs = e.bs[:slen+2]
480                 } else {
481                         e.bs = make([]byte, slen+2)
482                 }
483                 e.bs[0] = '"'
484                 base64.StdEncoding.Encode(e.bs[1:], v)
485                 e.bs[slen+1] = '"'
486                 e.ew.writeb(e.bs)
487         } else {
488                 e.quoteStr(stringView(v))
489         }
490 }
491
492 func (e *jsonEncDriver) EncodeAsis(v []byte) {
493         e.ew.writeb(v)
494 }
495
496 func (e *jsonEncDriver) quoteStr(s string) {
497         // adapted from std pkg encoding/json
498         const hex = "0123456789abcdef"
499         w := e.ew
500         htmlasis := e.h.HTMLCharsAsIs
501         w.writen1('"')
502         var start int
503         for i, slen := 0, len(s); i < slen; {
504                 // encode all bytes < 0x20 (except \r, \n).
505                 // also encode < > & to prevent security holes when served to some browsers.
506                 if b := s[i]; b < utf8.RuneSelf {
507                         // if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
508                         // if (htmlasis && jsonCharSafeSet.isset(b)) || jsonCharHtmlSafeSet.isset(b) {
509                         if jsonCharHtmlSafeSet.isset(b) || (htmlasis && jsonCharSafeSet.isset(b)) {
510                                 i++
511                                 continue
512                         }
513                         if start < i {
514                                 w.writestr(s[start:i])
515                         }
516                         switch b {
517                         case '\\', '"':
518                                 w.writen2('\\', b)
519                         case '\n':
520                                 w.writen2('\\', 'n')
521                         case '\r':
522                                 w.writen2('\\', 'r')
523                         case '\b':
524                                 w.writen2('\\', 'b')
525                         case '\f':
526                                 w.writen2('\\', 'f')
527                         case '\t':
528                                 w.writen2('\\', 't')
529                         default:
530                                 w.writestr(`\u00`)
531                                 w.writen2(hex[b>>4], hex[b&0xF])
532                         }
533                         i++
534                         start = i
535                         continue
536                 }
537                 c, size := utf8.DecodeRuneInString(s[i:])
538                 if c == utf8.RuneError && size == 1 {
539                         if start < i {
540                                 w.writestr(s[start:i])
541                         }
542                         w.writestr(`\ufffd`)
543                         i += size
544                         start = i
545                         continue
546                 }
547                 // U+2028 is LINE SEPARATOR. U+2029 is PARAGRAPH SEPARATOR.
548                 // Both technically valid JSON, but bomb on JSONP, so fix here unconditionally.
549                 if c == '\u2028' || c == '\u2029' {
550                         if start < i {
551                                 w.writestr(s[start:i])
552                         }
553                         w.writestr(`\u202`)
554                         w.writen1(hex[c&0xF])
555                         i += size
556                         start = i
557                         continue
558                 }
559                 i += size
560         }
561         if start < len(s) {
562                 w.writestr(s[start:])
563         }
564         w.writen1('"')
565 }
566
567 type jsonDecDriver struct {
568         noBuiltInTypes
569         d  *Decoder
570         h  *JsonHandle
571         r  decReader
572         se extWrapper
573
574         // ---- writable fields during execution --- *try* to keep in sep cache line
575
576         c containerState
577         // tok is used to store the token read right after skipWhiteSpace.
578         tok   uint8
579         fnull bool    // found null from appendStringAsBytes
580         bs    []byte  // scratch. Initialized from b. Used for parsing strings or numbers.
581         bstr  [8]byte // scratch used for string \UXXX parsing
582         // ---- cpu cache line boundary?
583         b  [jsonScratchArrayLen]byte // scratch 1, used for parsing strings or numbers or time.Time
584         b2 [jsonScratchArrayLen]byte // scratch 2, used only for readUntil, decNumBytes
585
586         _ [3]uint64 // padding
587         // n jsonNum
588 }
589
590 // func jsonIsWS(b byte) bool {
591 //      // return b == ' ' || b == '\t' || b == '\r' || b == '\n'
592 //      return jsonCharWhitespaceSet.isset(b)
593 // }
594
595 func (d *jsonDecDriver) uncacheRead() {
596         if d.tok != 0 {
597                 d.r.unreadn1()
598                 d.tok = 0
599         }
600 }
601
602 func (d *jsonDecDriver) ReadMapStart() int {
603         if d.tok == 0 {
604                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
605         }
606         const xc uint8 = '{'
607         if d.tok != xc {
608                 d.d.errorf("read map - expect char '%c' but got char '%c'", xc, d.tok)
609         }
610         d.tok = 0
611         d.c = containerMapStart
612         return -1
613 }
614
615 func (d *jsonDecDriver) ReadArrayStart() int {
616         if d.tok == 0 {
617                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
618         }
619         const xc uint8 = '['
620         if d.tok != xc {
621                 d.d.errorf("read array - expect char '%c' but got char '%c'", xc, d.tok)
622         }
623         d.tok = 0
624         d.c = containerArrayStart
625         return -1
626 }
627
628 func (d *jsonDecDriver) CheckBreak() bool {
629         if d.tok == 0 {
630                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
631         }
632         return d.tok == '}' || d.tok == ']'
633 }
634
635 // For the ReadXXX methods below, we could just delegate to helper functions
636 // readContainerState(c containerState, xc uint8, check bool)
637 // - ReadArrayElem would become:
638 //   readContainerState(containerArrayElem, ',', d.c != containerArrayStart)
639 //
640 // However, until mid-stack inlining comes in go1.11 which supports inlining of
641 // one-liners, we explicitly write them all 5 out to elide the extra func call.
642 //
643 // TODO: For Go 1.11, if inlined, consider consolidating these.
644
645 func (d *jsonDecDriver) ReadArrayElem() {
646         const xc uint8 = ','
647         if d.tok == 0 {
648                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
649         }
650         if d.c != containerArrayStart {
651                 if d.tok != xc {
652                         d.d.errorf("read array element - expect char '%c' but got char '%c'", xc, d.tok)
653                 }
654                 d.tok = 0
655         }
656         d.c = containerArrayElem
657 }
658
659 func (d *jsonDecDriver) ReadArrayEnd() {
660         const xc uint8 = ']'
661         if d.tok == 0 {
662                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
663         }
664         if d.tok != xc {
665                 d.d.errorf("read array end - expect char '%c' but got char '%c'", xc, d.tok)
666         }
667         d.tok = 0
668         d.c = containerArrayEnd
669 }
670
671 func (d *jsonDecDriver) ReadMapElemKey() {
672         const xc uint8 = ','
673         if d.tok == 0 {
674                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
675         }
676         if d.c != containerMapStart {
677                 if d.tok != xc {
678                         d.d.errorf("read map key - expect char '%c' but got char '%c'", xc, d.tok)
679                 }
680                 d.tok = 0
681         }
682         d.c = containerMapKey
683 }
684
685 func (d *jsonDecDriver) ReadMapElemValue() {
686         const xc uint8 = ':'
687         if d.tok == 0 {
688                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
689         }
690         if d.tok != xc {
691                 d.d.errorf("read map value - expect char '%c' but got char '%c'", xc, d.tok)
692         }
693         d.tok = 0
694         d.c = containerMapValue
695 }
696
697 func (d *jsonDecDriver) ReadMapEnd() {
698         const xc uint8 = '}'
699         if d.tok == 0 {
700                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
701         }
702         if d.tok != xc {
703                 d.d.errorf("read map end - expect char '%c' but got char '%c'", xc, d.tok)
704         }
705         d.tok = 0
706         d.c = containerMapEnd
707 }
708
709 func (d *jsonDecDriver) readLit(length, fromIdx uint8) {
710         // length here is always less than 8 (literals are: null, true, false)
711         bs := d.r.readx(int(length))
712         d.tok = 0
713         if jsonValidateSymbols && !bytes.Equal(bs, jsonLiterals[fromIdx:fromIdx+length]) {
714                 d.d.errorf("expecting %s: got %s", jsonLiterals[fromIdx:fromIdx+length], bs)
715                 return
716         }
717 }
718
719 func (d *jsonDecDriver) TryDecodeAsNil() bool {
720         if d.tok == 0 {
721                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
722         }
723         // we shouldn't try to see if "null" was here, right?
724         // only the plain string: `null` denotes a nil (ie not quotes)
725         if d.tok == 'n' {
726                 d.readLit(3, jsonLitNull+1) // (n)ull
727                 return true
728         }
729         return false
730 }
731
732 func (d *jsonDecDriver) DecodeBool() (v bool) {
733         if d.tok == 0 {
734                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
735         }
736         fquot := d.c == containerMapKey && d.tok == '"'
737         if fquot {
738                 d.tok = d.r.readn1()
739         }
740         switch d.tok {
741         case 'f':
742                 d.readLit(4, jsonLitFalse+1) // (f)alse
743                 // v = false
744         case 't':
745                 d.readLit(3, jsonLitTrue+1) // (t)rue
746                 v = true
747         default:
748                 d.d.errorf("decode bool: got first char %c", d.tok)
749                 // v = false // "unreachable"
750         }
751         if fquot {
752                 d.r.readn1()
753         }
754         return
755 }
756
757 func (d *jsonDecDriver) DecodeTime() (t time.Time) {
758         // read string, and pass the string into json.unmarshal
759         d.appendStringAsBytes()
760         if d.fnull {
761                 return
762         }
763         t, err := time.Parse(time.RFC3339, stringView(d.bs))
764         if err != nil {
765                 d.d.errorv(err)
766         }
767         return
768 }
769
770 func (d *jsonDecDriver) ContainerType() (vt valueType) {
771         // check container type by checking the first char
772         if d.tok == 0 {
773                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
774         }
775
776         // optimize this, so we don't do 4 checks but do one computation.
777         // return jsonContainerSet[d.tok]
778
779         // ContainerType is mostly called for Map and Array,
780         // so this conditional is good enough (max 2 checks typically)
781         if b := d.tok; b == '{' {
782                 return valueTypeMap
783         } else if b == '[' {
784                 return valueTypeArray
785         } else if b == 'n' {
786                 return valueTypeNil
787         } else if b == '"' {
788                 return valueTypeString
789         }
790         return valueTypeUnset
791 }
792
793 func (d *jsonDecDriver) decNumBytes() (bs []byte) {
794         // stores num bytes in d.bs
795         if d.tok == 0 {
796                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
797         }
798         if d.tok == '"' {
799                 bs = d.r.readUntil(d.b2[:0], '"')
800                 bs = bs[:len(bs)-1]
801         } else {
802                 d.r.unreadn1()
803                 bs = d.r.readTo(d.bs[:0], &jsonNumSet)
804         }
805         d.tok = 0
806         return bs
807 }
808
809 func (d *jsonDecDriver) DecodeUint64() (u uint64) {
810         bs := d.decNumBytes()
811         if len(bs) == 0 {
812                 return
813         }
814         n, neg, badsyntax, overflow := jsonParseInteger(bs)
815         if overflow {
816                 d.d.errorf("overflow parsing unsigned integer: %s", bs)
817         } else if neg {
818                 d.d.errorf("minus found parsing unsigned integer: %s", bs)
819         } else if badsyntax {
820                 // fallback: try to decode as float, and cast
821                 n = d.decUint64ViaFloat(stringView(bs))
822         }
823         return n
824 }
825
826 func (d *jsonDecDriver) DecodeInt64() (i int64) {
827         const cutoff = uint64(1 << uint(64-1))
828         bs := d.decNumBytes()
829         if len(bs) == 0 {
830                 return
831         }
832         n, neg, badsyntax, overflow := jsonParseInteger(bs)
833         if overflow {
834                 d.d.errorf("overflow parsing integer: %s", bs)
835         } else if badsyntax {
836                 // d.d.errorf("invalid syntax for integer: %s", bs)
837                 // fallback: try to decode as float, and cast
838                 if neg {
839                         n = d.decUint64ViaFloat(stringView(bs[1:]))
840                 } else {
841                         n = d.decUint64ViaFloat(stringView(bs))
842                 }
843         }
844         if neg {
845                 if n > cutoff {
846                         d.d.errorf("overflow parsing integer: %s", bs)
847                 }
848                 i = -(int64(n))
849         } else {
850                 if n >= cutoff {
851                         d.d.errorf("overflow parsing integer: %s", bs)
852                 }
853                 i = int64(n)
854         }
855         return
856 }
857
858 func (d *jsonDecDriver) decUint64ViaFloat(s string) (u uint64) {
859         if len(s) == 0 {
860                 return
861         }
862         f, err := strconv.ParseFloat(s, 64)
863         if err != nil {
864                 d.d.errorf("invalid syntax for integer: %s", s)
865                 // d.d.errorv(err)
866         }
867         fi, ff := math.Modf(f)
868         if ff > 0 {
869                 d.d.errorf("fractional part found parsing integer: %s", s)
870         } else if fi > float64(math.MaxUint64) {
871                 d.d.errorf("overflow parsing integer: %s", s)
872         }
873         return uint64(fi)
874 }
875
876 func (d *jsonDecDriver) DecodeFloat64() (f float64) {
877         bs := d.decNumBytes()
878         if len(bs) == 0 {
879                 return
880         }
881         f, err := strconv.ParseFloat(stringView(bs), 64)
882         if err != nil {
883                 d.d.errorv(err)
884         }
885         return
886 }
887
888 func (d *jsonDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
889         if ext == nil {
890                 re := rv.(*RawExt)
891                 re.Tag = xtag
892                 d.d.decode(&re.Value)
893         } else {
894                 var v interface{}
895                 d.d.decode(&v)
896                 ext.UpdateExt(rv, v)
897         }
898         return
899 }
900
901 func (d *jsonDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
902         // if decoding into raw bytes, and the RawBytesExt is configured, use it to decode.
903         if d.se.InterfaceExt != nil {
904                 bsOut = bs
905                 d.DecodeExt(&bsOut, 0, &d.se)
906                 return
907         }
908         if d.tok == 0 {
909                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
910         }
911         // check if an "array" of uint8's (see ContainerType for how to infer if an array)
912         if d.tok == '[' {
913                 bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
914                 return
915         }
916         d.appendStringAsBytes()
917         // base64 encodes []byte{} as "", and we encode nil []byte as null.
918         // Consequently, base64 should decode null as a nil []byte, and "" as an empty []byte{}.
919         // appendStringAsBytes returns a zero-len slice for both, so as not to reset d.bs.
920         // However, it sets a fnull field to true, so we can check if a null was found.
921         if len(d.bs) == 0 {
922                 if d.fnull {
923                         return nil
924                 }
925                 return []byte{}
926         }
927         bs0 := d.bs
928         slen := base64.StdEncoding.DecodedLen(len(bs0))
929         if slen <= cap(bs) {
930                 bsOut = bs[:slen]
931         } else if zerocopy && slen <= cap(d.b2) {
932                 bsOut = d.b2[:slen]
933         } else {
934                 bsOut = make([]byte, slen)
935         }
936         slen2, err := base64.StdEncoding.Decode(bsOut, bs0)
937         if err != nil {
938                 d.d.errorf("error decoding base64 binary '%s': %v", bs0, err)
939                 return nil
940         }
941         if slen != slen2 {
942                 bsOut = bsOut[:slen2]
943         }
944         return
945 }
946
947 func (d *jsonDecDriver) DecodeString() (s string) {
948         d.appendStringAsBytes()
949         return d.bsToString()
950 }
951
952 func (d *jsonDecDriver) DecodeStringAsBytes() (s []byte) {
953         d.appendStringAsBytes()
954         return d.bs
955 }
956
957 func (d *jsonDecDriver) appendStringAsBytes() {
958         if d.tok == 0 {
959                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
960         }
961
962         d.fnull = false
963         if d.tok != '"' {
964                 // d.d.errorf("expect char '%c' but got char '%c'", '"', d.tok)
965                 // handle non-string scalar: null, true, false or a number
966                 switch d.tok {
967                 case 'n':
968                         d.readLit(3, jsonLitNull+1) // (n)ull
969                         d.bs = d.bs[:0]
970                         d.fnull = true
971                 case 'f':
972                         d.readLit(4, jsonLitFalse+1) // (f)alse
973                         d.bs = d.bs[:5]
974                         copy(d.bs, "false")
975                 case 't':
976                         d.readLit(3, jsonLitTrue+1) // (t)rue
977                         d.bs = d.bs[:4]
978                         copy(d.bs, "true")
979                 default:
980                         // try to parse a valid number
981                         bs := d.decNumBytes()
982                         if len(bs) <= cap(d.bs) {
983                                 d.bs = d.bs[:len(bs)]
984                         } else {
985                                 d.bs = make([]byte, len(bs))
986                         }
987                         copy(d.bs, bs)
988                 }
989                 return
990         }
991
992         d.tok = 0
993         r := d.r
994         var cs = r.readUntil(d.b2[:0], '"')
995         var cslen = len(cs)
996         var c uint8
997         v := d.bs[:0]
998         // append on each byte seen can be expensive, so we just
999         // keep track of where we last read a contiguous set of
1000         // non-special bytes (using cursor variable),
1001         // and when we see a special byte
1002         // e.g. end-of-slice, " or \,
1003         // we will append the full range into the v slice before proceeding
1004         for i, cursor := 0, 0; ; {
1005                 if i == cslen {
1006                         v = append(v, cs[cursor:]...)
1007                         cs = r.readUntil(d.b2[:0], '"')
1008                         cslen = len(cs)
1009                         i, cursor = 0, 0
1010                 }
1011                 c = cs[i]
1012                 if c == '"' {
1013                         v = append(v, cs[cursor:i]...)
1014                         break
1015                 }
1016                 if c != '\\' {
1017                         i++
1018                         continue
1019                 }
1020                 v = append(v, cs[cursor:i]...)
1021                 i++
1022                 c = cs[i]
1023                 switch c {
1024                 case '"', '\\', '/', '\'':
1025                         v = append(v, c)
1026                 case 'b':
1027                         v = append(v, '\b')
1028                 case 'f':
1029                         v = append(v, '\f')
1030                 case 'n':
1031                         v = append(v, '\n')
1032                 case 'r':
1033                         v = append(v, '\r')
1034                 case 't':
1035                         v = append(v, '\t')
1036                 case 'u':
1037                         var r rune
1038                         var rr uint32
1039                         if len(cs) < i+4 { // may help reduce bounds-checking
1040                                 d.d.errorf("need at least 4 more bytes for unicode sequence")
1041                         }
1042                         // c = cs[i+4] // may help reduce bounds-checking
1043                         for j := 1; j < 5; j++ {
1044                                 // best to use explicit if-else
1045                                 // - not a table, etc which involve memory loads, array lookup with bounds checks, etc
1046                                 c = cs[i+j]
1047                                 if c >= '0' && c <= '9' {
1048                                         rr = rr*16 + uint32(c-jsonU4Chk2)
1049                                 } else if c >= 'a' && c <= 'f' {
1050                                         rr = rr*16 + uint32(c-jsonU4Chk1)
1051                                 } else if c >= 'A' && c <= 'F' {
1052                                         rr = rr*16 + uint32(c-jsonU4Chk0)
1053                                 } else {
1054                                         r = unicode.ReplacementChar
1055                                         i += 4
1056                                         goto encode_rune
1057                                 }
1058                         }
1059                         r = rune(rr)
1060                         i += 4
1061                         if utf16.IsSurrogate(r) {
1062                                 if len(cs) >= i+6 && cs[i+2] == 'u' && cs[i+1] == '\\' {
1063                                         i += 2
1064                                         // c = cs[i+4] // may help reduce bounds-checking
1065                                         var rr1 uint32
1066                                         for j := 1; j < 5; j++ {
1067                                                 c = cs[i+j]
1068                                                 if c >= '0' && c <= '9' {
1069                                                         rr = rr*16 + uint32(c-jsonU4Chk2)
1070                                                 } else if c >= 'a' && c <= 'f' {
1071                                                         rr = rr*16 + uint32(c-jsonU4Chk1)
1072                                                 } else if c >= 'A' && c <= 'F' {
1073                                                         rr = rr*16 + uint32(c-jsonU4Chk0)
1074                                                 } else {
1075                                                         r = unicode.ReplacementChar
1076                                                         i += 4
1077                                                         goto encode_rune
1078                                                 }
1079                                         }
1080                                         r = utf16.DecodeRune(r, rune(rr1))
1081                                         i += 4
1082                                 } else {
1083                                         r = unicode.ReplacementChar
1084                                         goto encode_rune
1085                                 }
1086                         }
1087                 encode_rune:
1088                         w2 := utf8.EncodeRune(d.bstr[:], r)
1089                         v = append(v, d.bstr[:w2]...)
1090                 default:
1091                         d.d.errorf("unsupported escaped value: %c", c)
1092                 }
1093                 i++
1094                 cursor = i
1095         }
1096         d.bs = v
1097 }
1098
1099 func (d *jsonDecDriver) nakedNum(z *decNaked, bs []byte) (err error) {
1100         const cutoff = uint64(1 << uint(64-1))
1101
1102         var n uint64
1103         var neg, badsyntax, overflow bool
1104
1105         if len(bs) == 0 {
1106                 if d.h.PreferFloat {
1107                         z.v = valueTypeFloat
1108                         z.f = 0
1109                 } else if d.h.SignedInteger {
1110                         z.v = valueTypeInt
1111                         z.i = 0
1112                 } else {
1113                         z.v = valueTypeUint
1114                         z.u = 0
1115                 }
1116                 return
1117         }
1118         if d.h.PreferFloat {
1119                 goto F
1120         }
1121         n, neg, badsyntax, overflow = jsonParseInteger(bs)
1122         if badsyntax || overflow {
1123                 goto F
1124         }
1125         if neg {
1126                 if n > cutoff {
1127                         goto F
1128                 }
1129                 z.v = valueTypeInt
1130                 z.i = -(int64(n))
1131         } else if d.h.SignedInteger {
1132                 if n >= cutoff {
1133                         goto F
1134                 }
1135                 z.v = valueTypeInt
1136                 z.i = int64(n)
1137         } else {
1138                 z.v = valueTypeUint
1139                 z.u = n
1140         }
1141         return
1142 F:
1143         z.v = valueTypeFloat
1144         z.f, err = strconv.ParseFloat(stringView(bs), 64)
1145         return
1146 }
1147
1148 func (d *jsonDecDriver) bsToString() string {
1149         // if x := d.s.sc; x != nil && x.so && x.st == '}' { // map key
1150         if jsonAlwaysReturnInternString || d.c == containerMapKey {
1151                 return d.d.string(d.bs)
1152         }
1153         return string(d.bs)
1154 }
1155
1156 func (d *jsonDecDriver) DecodeNaked() {
1157         z := d.d.n
1158         // var decodeFurther bool
1159
1160         if d.tok == 0 {
1161                 d.tok = d.r.skip(&jsonCharWhitespaceSet)
1162         }
1163         switch d.tok {
1164         case 'n':
1165                 d.readLit(3, jsonLitNull+1) // (n)ull
1166                 z.v = valueTypeNil
1167         case 'f':
1168                 d.readLit(4, jsonLitFalse+1) // (f)alse
1169                 z.v = valueTypeBool
1170                 z.b = false
1171         case 't':
1172                 d.readLit(3, jsonLitTrue+1) // (t)rue
1173                 z.v = valueTypeBool
1174                 z.b = true
1175         case '{':
1176                 z.v = valueTypeMap // don't consume. kInterfaceNaked will call ReadMapStart
1177         case '[':
1178                 z.v = valueTypeArray // don't consume. kInterfaceNaked will call ReadArrayStart
1179         case '"':
1180                 // if a string, and MapKeyAsString, then try to decode it as a nil, bool or number first
1181                 d.appendStringAsBytes()
1182                 if len(d.bs) > 0 && d.c == containerMapKey && d.h.MapKeyAsString {
1183                         switch stringView(d.bs) {
1184                         case "null":
1185                                 z.v = valueTypeNil
1186                         case "true":
1187                                 z.v = valueTypeBool
1188                                 z.b = true
1189                         case "false":
1190                                 z.v = valueTypeBool
1191                                 z.b = false
1192                         default:
1193                                 // check if a number: float, int or uint
1194                                 if err := d.nakedNum(z, d.bs); err != nil {
1195                                         z.v = valueTypeString
1196                                         z.s = d.bsToString()
1197                                 }
1198                         }
1199                 } else {
1200                         z.v = valueTypeString
1201                         z.s = d.bsToString()
1202                 }
1203         default: // number
1204                 bs := d.decNumBytes()
1205                 if len(bs) == 0 {
1206                         d.d.errorf("decode number from empty string")
1207                         return
1208                 }
1209                 if err := d.nakedNum(z, bs); err != nil {
1210                         d.d.errorf("decode number from %s: %v", bs, err)
1211                         return
1212                 }
1213         }
1214         // if decodeFurther {
1215         //      d.s.sc.retryRead()
1216         // }
1217         return
1218 }
1219
1220 //----------------------
1221
1222 // JsonHandle is a handle for JSON encoding format.
1223 //
1224 // Json is comprehensively supported:
1225 //    - decodes numbers into interface{} as int, uint or float64
1226 //      based on how the number looks and some config parameters e.g. PreferFloat, SignedInt, etc.
1227 //    - decode integers from float formatted numbers e.g. 1.27e+8
1228 //    - decode any json value (numbers, bool, etc) from quoted strings
1229 //    - configurable way to encode/decode []byte .
1230 //      by default, encodes and decodes []byte using base64 Std Encoding
1231 //    - UTF-8 support for encoding and decoding
1232 //
1233 // It has better performance than the json library in the standard library,
1234 // by leveraging the performance improvements of the codec library.
1235 //
1236 // In addition, it doesn't read more bytes than necessary during a decode, which allows
1237 // reading multiple values from a stream containing json and non-json content.
1238 // For example, a user can read a json value, then a cbor value, then a msgpack value,
1239 // all from the same stream in sequence.
1240 //
1241 // Note that, when decoding quoted strings, invalid UTF-8 or invalid UTF-16 surrogate pairs are
1242 // not treated as an error. Instead, they are replaced by the Unicode replacement character U+FFFD.
1243 type JsonHandle struct {
1244         textEncodingType
1245         BasicHandle
1246
1247         // Indent indicates how a value is encoded.
1248         //   - If positive, indent by that number of spaces.
1249         //   - If negative, indent by that number of tabs.
1250         Indent int8
1251
1252         // IntegerAsString controls how integers (signed and unsigned) are encoded.
1253         //
1254         // Per the JSON Spec, JSON numbers are 64-bit floating point numbers.
1255         // Consequently, integers > 2^53 cannot be represented as a JSON number without losing precision.
1256         // This can be mitigated by configuring how to encode integers.
1257         //
1258         // IntegerAsString interpretes the following values:
1259         //   - if 'L', then encode integers > 2^53 as a json string.
1260         //   - if 'A', then encode all integers as a json string
1261         //             containing the exact integer representation as a decimal.
1262         //   - else    encode all integers as a json number (default)
1263         IntegerAsString byte
1264
1265         // HTMLCharsAsIs controls how to encode some special characters to html: < > &
1266         //
1267         // By default, we encode them as \uXXX
1268         // to prevent security holes when served from some browsers.
1269         HTMLCharsAsIs bool
1270
1271         // PreferFloat says that we will default to decoding a number as a float.
1272         // If not set, we will examine the characters of the number and decode as an
1273         // integer type if it doesn't have any of the characters [.eE].
1274         PreferFloat bool
1275
1276         // TermWhitespace says that we add a whitespace character
1277         // at the end of an encoding.
1278         //
1279         // The whitespace is important, especially if using numbers in a context
1280         // where multiple items are written to a stream.
1281         TermWhitespace bool
1282
1283         // MapKeyAsString says to encode all map keys as strings.
1284         //
1285         // Use this to enforce strict json output.
1286         // The only caveat is that nil value is ALWAYS written as null (never as "null")
1287         MapKeyAsString bool
1288
1289         // _ [2]byte // padding
1290
1291         // Note: below, we store hardly-used items e.g. RawBytesExt is cached in the (en|de)cDriver.
1292
1293         // RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way.
1294         // If not configured, raw bytes are encoded to/from base64 text.
1295         RawBytesExt InterfaceExt
1296
1297         _ [2]uint64 // padding
1298 }
1299
1300 // Name returns the name of the handle: json
1301 func (h *JsonHandle) Name() string            { return "json" }
1302 func (h *JsonHandle) hasElemSeparators() bool { return true }
1303 func (h *JsonHandle) typical() bool {
1304         return h.Indent == 0 && !h.MapKeyAsString && h.IntegerAsString != 'A' && h.IntegerAsString != 'L'
1305 }
1306
1307 type jsonTypical interface {
1308         typical()
1309 }
1310
1311 func (h *JsonHandle) recreateEncDriver(ed encDriver) (v bool) {
1312         _, v = ed.(jsonTypical)
1313         return v != h.typical()
1314 }
1315
1316 // SetInterfaceExt sets an extension
1317 func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
1318         return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
1319 }
1320
1321 type jsonEncDriverTypicalImpl struct {
1322         jsonEncDriver
1323         jsonEncDriverTypical
1324         _ [3]uint64 // padding
1325 }
1326
1327 func (x *jsonEncDriverTypicalImpl) reset() {
1328         x.jsonEncDriver.reset()
1329         x.jsonEncDriverTypical.reset(&x.jsonEncDriver)
1330 }
1331
1332 type jsonEncDriverGenericImpl struct {
1333         jsonEncDriver
1334         jsonEncDriverGeneric
1335         _ [2]uint64 // padding
1336 }
1337
1338 func (x *jsonEncDriverGenericImpl) reset() {
1339         x.jsonEncDriver.reset()
1340         x.jsonEncDriverGeneric.reset(&x.jsonEncDriver)
1341 }
1342
1343 func (h *JsonHandle) newEncDriver(e *Encoder) (ee encDriver) {
1344         var hd *jsonEncDriver
1345         if h.typical() {
1346                 var v jsonEncDriverTypicalImpl
1347                 ee = &v
1348                 hd = &v.jsonEncDriver
1349         } else {
1350                 var v jsonEncDriverGenericImpl
1351                 ee = &v
1352                 hd = &v.jsonEncDriver
1353         }
1354         hd.e, hd.h, hd.bs = e, h, hd.b[:0]
1355         hd.se.BytesExt = bytesExtFailer{}
1356         ee.reset()
1357         return
1358 }
1359
1360 func (h *JsonHandle) newDecDriver(d *Decoder) decDriver {
1361         // d := jsonDecDriver{r: r.(*bytesDecReader), h: h}
1362         hd := jsonDecDriver{d: d, h: h}
1363         hd.se.BytesExt = bytesExtFailer{}
1364         hd.bs = hd.b[:0]
1365         hd.reset()
1366         return &hd
1367 }
1368
1369 func (e *jsonEncDriver) reset() {
1370         e.ew = e.e.w
1371         e.se.InterfaceExt = e.h.RawBytesExt
1372         if e.bs != nil {
1373                 e.bs = e.bs[:0]
1374         }
1375 }
1376
1377 func (d *jsonDecDriver) reset() {
1378         d.r = d.d.r
1379         d.se.InterfaceExt = d.h.RawBytesExt
1380         if d.bs != nil {
1381                 d.bs = d.bs[:0]
1382         }
1383         d.c, d.tok = 0, 0
1384         // d.n.reset()
1385 }
1386
1387 func jsonFloatStrconvFmtPrec(f float64) (fmt byte, prec int) {
1388         prec = -1
1389         var abs = math.Abs(f)
1390         if abs != 0 && (abs < 1e-6 || abs >= 1e21) {
1391                 fmt = 'e'
1392         } else {
1393                 fmt = 'f'
1394                 // set prec to 1 iff mod is 0.
1395                 //     better than using jsonIsFloatBytesB2 to check if a . or E in the float bytes.
1396                 // this ensures that every float has an e or .0 in it.
1397                 if abs <= 1 {
1398                         if abs == 0 || abs == 1 {
1399                                 prec = 1
1400                         }
1401                 } else if _, mod := math.Modf(abs); mod == 0 {
1402                         prec = 1
1403                 }
1404         }
1405         return
1406 }
1407
1408 // custom-fitted version of strconv.Parse(Ui|I)nt.
1409 // Also ensures we don't have to search for .eE to determine if a float or not.
1410 // Note: s CANNOT be a zero-length slice.
1411 func jsonParseInteger(s []byte) (n uint64, neg, badSyntax, overflow bool) {
1412         const maxUint64 = (1<<64 - 1)
1413         const cutoff = maxUint64/10 + 1
1414
1415         // if len(s) == 0 {
1416         //      // treat empty string as zero value
1417         //      // badSyntax = true
1418         //      return
1419         // }
1420         switch s[0] {
1421         case '+':
1422                 s = s[1:]
1423         case '-':
1424                 s = s[1:]
1425                 neg = true
1426         }
1427         for _, c := range s {
1428                 if c < '0' || c > '9' {
1429                         badSyntax = true
1430                         return
1431                 }
1432                 // unsigned integers don't overflow well on multiplication, so check cutoff here
1433                 // e.g. (maxUint64-5)*10 doesn't overflow well ...
1434                 if n >= cutoff {
1435                         overflow = true
1436                         return
1437                 }
1438                 n *= 10
1439                 n1 := n + uint64(c-'0')
1440                 if n1 < n || n1 > maxUint64 {
1441                         overflow = true
1442                         return
1443                 }
1444                 n = n1
1445         }
1446         return
1447 }
1448
1449 var _ decDriver = (*jsonDecDriver)(nil)
1450 var _ encDriver = (*jsonEncDriverGenericImpl)(nil)
1451 var _ encDriver = (*jsonEncDriverTypicalImpl)(nil)
1452 var _ jsonTypical = (*jsonEncDriverTypical)(nil)