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