github.com/ugorji/go/codec@v1.2.13-0.20240307214044-07c54c229a5a/json.go (about)

     1  // Copyright (c) 2012-2020 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  // We cannot use strconv.(Q|Unq)uote because json quotes/unquotes differently.
    18  
    19  import (
    20  	"encoding/base64"
    21  	"math"
    22  	"reflect"
    23  	"strconv"
    24  	"time"
    25  	"unicode"
    26  	"unicode/utf16"
    27  	"unicode/utf8"
    28  )
    29  
    30  //--------------------------------
    31  
    32  // jsonLits and jsonLitb are defined at the package level,
    33  // so they are guaranteed to be stored efficiently, making
    34  // for better append/string comparison/etc.
    35  //
    36  // (anecdotal evidence from some benchmarking on go 1.20 devel in 20220104)
    37  const jsonLits = `"true"false"null"`
    38  
    39  var jsonLitb = []byte(jsonLits)
    40  
    41  const (
    42  	jsonLitT = 1
    43  	jsonLitF = 6
    44  	jsonLitN = 12
    45  )
    46  
    47  const jsonEncodeUintSmallsString = "" +
    48  	"00010203040506070809" +
    49  	"10111213141516171819" +
    50  	"20212223242526272829" +
    51  	"30313233343536373839" +
    52  	"40414243444546474849" +
    53  	"50515253545556575859" +
    54  	"60616263646566676869" +
    55  	"70717273747576777879" +
    56  	"80818283848586878889" +
    57  	"90919293949596979899"
    58  
    59  var jsonEncodeUintSmallsStringBytes = []byte(jsonEncodeUintSmallsString)
    60  
    61  const (
    62  	jsonU4Chk2 = '0'
    63  	jsonU4Chk1 = 'a' - 10
    64  	jsonU4Chk0 = 'A' - 10
    65  )
    66  
    67  const (
    68  	// If !jsonValidateSymbols, decoding will be faster, by skipping some checks:
    69  	//   - If we see first character of null, false or true,
    70  	//     do not validate subsequent characters.
    71  	//   - e.g. if we see a n, assume null and skip next 3 characters,
    72  	//     and do not validate they are ull.
    73  	// P.S. Do not expect a significant decoding boost from this.
    74  	jsonValidateSymbols = true
    75  
    76  	// jsonEscapeMultiByteUnicodeSep controls whether some unicode characters
    77  	// that are valid json but may bomb in some contexts are escaped during encoeing.
    78  	//
    79  	// U+2028 is LINE SEPARATOR. U+2029 is PARAGRAPH SEPARATOR.
    80  	// Both technically valid JSON, but bomb on JSONP, so fix here unconditionally.
    81  	jsonEscapeMultiByteUnicodeSep = true
    82  
    83  	// jsonRecognizeBoolNullInQuotedStr is used during decoding into a blank interface{}
    84  	// to control whether we detect quoted values of bools and null where a map key is expected,
    85  	// and treat as nil, true or false.
    86  	jsonNakedBoolNullInQuotedStr = true
    87  
    88  	// jsonManualInlineDecRdInHotZones controls whether we manually inline some decReader calls.
    89  	//
    90  	// encode performance is at par with libraries that just iterate over bytes directly,
    91  	// because encWr (with inlined bytesEncAppender calls) is inlined.
    92  	// Conversely, decode performance suffers because decRd (with inlined bytesDecReader calls)
    93  	// isn't inlinable.
    94  	//
    95  	// To improve decode performamnce from json:
    96  	// - readn1 is only called for \u
    97  	// - consequently, to optimize json decoding, we specifically need inlining
    98  	//   for bytes use-case of some other decReader methods:
    99  	//   - jsonReadAsisChars, skipWhitespace (advance) and jsonReadNum
   100  	//   - AND THEN readn3, readn4 (for ull, rue and alse).
   101  	//   - (readn1 is only called when a char is escaped).
   102  	// - without inlining, we still pay the cost of a method invocationK, and this dominates time
   103  	// - To mitigate, we manually inline in hot zones
   104  	//   *excluding places where used sparingly (e.g. nextValueBytes, and other atypical cases)*.
   105  	//   - jsonReadAsisChars *only* called in: appendStringAsBytes
   106  	//   - advance called: everywhere
   107  	//   - jsonReadNum: decNumBytes, DecodeNaked
   108  	// - From running go test (our anecdotal findings):
   109  	//   - calling jsonReadAsisChars in appendStringAsBytes: 23431
   110  	//   - calling jsonReadNum in decNumBytes: 15251
   111  	//   - calling jsonReadNum in DecodeNaked: 612
   112  	// Consequently, we manually inline jsonReadAsisChars (in appendStringAsBytes)
   113  	// and jsonReadNum (in decNumbytes)
   114  	jsonManualInlineDecRdInHotZones = true
   115  
   116  	jsonSpacesOrTabsLen = 128
   117  
   118  	// jsonAlwaysReturnInternString = false
   119  )
   120  
   121  var (
   122  	// jsonTabs and jsonSpaces are used as caches for indents
   123  	jsonTabs, jsonSpaces [jsonSpacesOrTabsLen]byte
   124  
   125  	jsonCharHtmlSafeSet bitset256
   126  	jsonCharSafeSet     bitset256
   127  )
   128  
   129  func init() {
   130  	var i byte
   131  	for i = 0; i < jsonSpacesOrTabsLen; i++ {
   132  		jsonSpaces[i] = ' '
   133  		jsonTabs[i] = '\t'
   134  	}
   135  
   136  	// populate the safe values as true: note: ASCII control characters are (0-31)
   137  	// jsonCharSafeSet:     all true except (0-31) " \
   138  	// jsonCharHtmlSafeSet: all true except (0-31) " \ < > &
   139  	for i = 32; i < utf8.RuneSelf; i++ {
   140  		switch i {
   141  		case '"', '\\':
   142  		case '<', '>', '&':
   143  			jsonCharSafeSet.set(i) // = true
   144  		default:
   145  			jsonCharSafeSet.set(i)
   146  			jsonCharHtmlSafeSet.set(i)
   147  		}
   148  	}
   149  }
   150  
   151  // ----------------
   152  
   153  type jsonEncState struct {
   154  	di int8   // indent per: if negative, use tabs
   155  	d  bool   // indenting?
   156  	dl uint16 // indent level
   157  }
   158  
   159  func (x jsonEncState) captureState() interface{}   { return x }
   160  func (x *jsonEncState) restoreState(v interface{}) { *x = v.(jsonEncState) }
   161  
   162  type jsonEncDriver struct {
   163  	noBuiltInTypes
   164  	h *JsonHandle
   165  
   166  	// se interfaceExtWrapper
   167  
   168  	// ---- cpu cache line boundary?
   169  	jsonEncState
   170  
   171  	ks bool // map key as string
   172  	is byte // integer as string
   173  
   174  	typical bool
   175  	rawext  bool // rawext configured on the handle
   176  
   177  	s *bitset256 // safe set for characters (taking h.HTMLAsIs into consideration)
   178  
   179  	// buf *[]byte // used mostly for encoding []byte
   180  
   181  	// scratch buffer for: encode time, numbers, etc
   182  	//
   183  	// RFC3339Nano uses 35 chars: 2006-01-02T15:04:05.999999999Z07:00
   184  	// MaxUint64 uses 20 chars: 18446744073709551615
   185  	// floats are encoded using: f/e fmt, and -1 precision, or 1 if no fractions.
   186  	// This means we are limited by the number of characters for the
   187  	// mantissa (up to 17), exponent (up to 3), signs (up to 3), dot (up to 1), E (up to 1)
   188  	// for a total of 24 characters.
   189  	//    -xxx.yyyyyyyyyyyye-zzz
   190  	// Consequently, 35 characters should be sufficient for encoding time, integers or floats.
   191  	// We use up all the remaining bytes to make this use full cache lines.
   192  	b [48]byte
   193  
   194  	e Encoder
   195  }
   196  
   197  func (e *jsonEncDriver) encoder() *Encoder { return &e.e }
   198  
   199  func (e *jsonEncDriver) writeIndent() {
   200  	e.e.encWr.writen1('\n')
   201  	x := int(e.di) * int(e.dl)
   202  	if e.di < 0 {
   203  		x = -x
   204  		for x > jsonSpacesOrTabsLen {
   205  			e.e.encWr.writeb(jsonTabs[:])
   206  			x -= jsonSpacesOrTabsLen
   207  		}
   208  		e.e.encWr.writeb(jsonTabs[:x])
   209  	} else {
   210  		for x > jsonSpacesOrTabsLen {
   211  			e.e.encWr.writeb(jsonSpaces[:])
   212  			x -= jsonSpacesOrTabsLen
   213  		}
   214  		e.e.encWr.writeb(jsonSpaces[:x])
   215  	}
   216  }
   217  
   218  func (e *jsonEncDriver) WriteArrayElem() {
   219  	if e.e.c != containerArrayStart {
   220  		e.e.encWr.writen1(',')
   221  	}
   222  	if e.d {
   223  		e.writeIndent()
   224  	}
   225  }
   226  
   227  func (e *jsonEncDriver) WriteMapElemKey() {
   228  	if e.e.c != containerMapStart {
   229  		e.e.encWr.writen1(',')
   230  	}
   231  	if e.d {
   232  		e.writeIndent()
   233  	}
   234  }
   235  
   236  func (e *jsonEncDriver) WriteMapElemValue() {
   237  	if e.d {
   238  		e.e.encWr.writen2(':', ' ')
   239  	} else {
   240  		e.e.encWr.writen1(':')
   241  	}
   242  }
   243  
   244  func (e *jsonEncDriver) EncodeNil() {
   245  	// We always encode nil as just null (never in quotes)
   246  	// so we can easily decode if a nil in the json stream ie if initial token is n.
   247  
   248  	e.e.encWr.writestr(jsonLits[jsonLitN : jsonLitN+4])
   249  }
   250  
   251  func (e *jsonEncDriver) EncodeTime(t time.Time) {
   252  	// Do NOT use MarshalJSON, as it allocates internally.
   253  	// instead, we call AppendFormat directly, using our scratch buffer (e.b)
   254  
   255  	if t.IsZero() {
   256  		e.EncodeNil()
   257  	} else {
   258  		e.b[0] = '"'
   259  		b := fmtTime(t, time.RFC3339Nano, e.b[1:1])
   260  		e.b[len(b)+1] = '"'
   261  		e.e.encWr.writeb(e.b[:len(b)+2])
   262  	}
   263  }
   264  
   265  func (e *jsonEncDriver) EncodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) {
   266  	if ext == SelfExt {
   267  		e.e.encodeValue(baseRV(rv), e.h.fnNoExt(basetype))
   268  	} else if v := ext.ConvertExt(rv); v == nil {
   269  		e.EncodeNil()
   270  	} else {
   271  		e.e.encode(v)
   272  	}
   273  }
   274  
   275  func (e *jsonEncDriver) EncodeRawExt(re *RawExt) {
   276  	// only encodes re.Value (never re.Data)
   277  	if re.Value == nil {
   278  		e.EncodeNil()
   279  	} else {
   280  		e.e.encode(re.Value)
   281  	}
   282  }
   283  
   284  var jsonEncBoolStrs = [2][2]string{
   285  	{jsonLits[jsonLitF : jsonLitF+5], jsonLits[jsonLitT : jsonLitT+4]},
   286  	{jsonLits[jsonLitF-1 : jsonLitF+6], jsonLits[jsonLitT-1 : jsonLitT+5]},
   287  }
   288  
   289  func (e *jsonEncDriver) EncodeBool(b bool) {
   290  	e.e.encWr.writestr(
   291  		jsonEncBoolStrs[bool2int(e.ks && e.e.c == containerMapKey)%2][bool2int(b)%2])
   292  }
   293  
   294  // func (e *jsonEncDriver) EncodeBool(b bool) {
   295  // 	if e.ks && e.e.c == containerMapKey {
   296  // 		if b {
   297  // 			e.e.encWr.writestr(jsonLits[jsonLitT-1 : jsonLitT+5])
   298  // 		} else {
   299  // 			e.e.encWr.writestr(jsonLits[jsonLitF-1 : jsonLitF+6])
   300  // 		}
   301  // 	} else {
   302  // 		if b {
   303  // 			e.e.encWr.writestr(jsonLits[jsonLitT : jsonLitT+4])
   304  // 		} else {
   305  // 			e.e.encWr.writestr(jsonLits[jsonLitF : jsonLitF+5])
   306  // 		}
   307  // 	}
   308  // }
   309  
   310  func (e *jsonEncDriver) encodeFloat(f float64, bitsize, fmt byte, prec int8) {
   311  	var blen uint
   312  	if e.ks && e.e.c == containerMapKey {
   313  		blen = 2 + uint(len(strconv.AppendFloat(e.b[1:1], f, fmt, int(prec), int(bitsize))))
   314  		// _ = e.b[:blen]
   315  		e.b[0] = '"'
   316  		e.b[blen-1] = '"'
   317  		e.e.encWr.writeb(e.b[:blen])
   318  	} else {
   319  		e.e.encWr.writeb(strconv.AppendFloat(e.b[:0], f, fmt, int(prec), int(bitsize)))
   320  	}
   321  }
   322  
   323  func (e *jsonEncDriver) EncodeFloat64(f float64) {
   324  	if math.IsNaN(f) || math.IsInf(f, 0) {
   325  		e.EncodeNil()
   326  		return
   327  	}
   328  	fmt, prec := jsonFloatStrconvFmtPrec64(f)
   329  	e.encodeFloat(f, 64, fmt, prec)
   330  }
   331  
   332  func (e *jsonEncDriver) EncodeFloat32(f float32) {
   333  	if math.IsNaN(float64(f)) || math.IsInf(float64(f), 0) {
   334  		e.EncodeNil()
   335  		return
   336  	}
   337  	fmt, prec := jsonFloatStrconvFmtPrec32(f)
   338  	e.encodeFloat(float64(f), 32, fmt, prec)
   339  }
   340  
   341  func (e *jsonEncDriver) encodeUint(neg bool, quotes bool, u uint64) {
   342  	// copied mostly from std library: strconv
   343  	// this should only be called on 64bit OS.
   344  
   345  	// const smallsString = jsonEncodeUintSmallsString
   346  	var ss = jsonEncodeUintSmallsStringBytes
   347  
   348  	// typically, 19 or 20 bytes sufficient for decimal encoding a uint64
   349  	// var a [24]byte
   350  	var a = e.b[0:24]
   351  	var i = uint(len(a))
   352  
   353  	if quotes {
   354  		i--
   355  		setByteAt(a, i, '"')
   356  		// a[i] = '"'
   357  	}
   358  	// u guaranteed to fit into a uint (as we are not 32bit OS)
   359  	var is uint
   360  	var us = uint(u)
   361  	for us >= 100 {
   362  		is = us % 100 * 2
   363  		us /= 100
   364  		i -= 2
   365  		setByteAt(a, i+1, byteAt(ss, is+1))
   366  		setByteAt(a, i, byteAt(ss, is))
   367  		// a[i+1] = smallsString[is+1]
   368  		// a[i+0] = smallsString[is+0]
   369  	}
   370  
   371  	// us < 100
   372  	is = us * 2
   373  	i--
   374  	setByteAt(a, i, byteAt(ss, is+1))
   375  	// a[i] = smallsString[is+1]
   376  	if us >= 10 {
   377  		i--
   378  		setByteAt(a, i, byteAt(ss, is))
   379  		// a[i] = smallsString[is]
   380  	}
   381  	if neg {
   382  		i--
   383  		setByteAt(a, i, '-')
   384  		// a[i] = '-'
   385  	}
   386  	if quotes {
   387  		i--
   388  		setByteAt(a, i, '"')
   389  		// a[i] = '"'
   390  	}
   391  	e.e.encWr.writeb(a[i:])
   392  }
   393  
   394  func (e *jsonEncDriver) EncodeInt(v int64) {
   395  	quotes := e.is == 'A' || e.is == 'L' && (v > 1<<53 || v < -(1<<53)) ||
   396  		(e.ks && e.e.c == containerMapKey)
   397  
   398  	if cpu32Bit {
   399  		if quotes {
   400  			blen := 2 + len(strconv.AppendInt(e.b[1:1], v, 10))
   401  			e.b[0] = '"'
   402  			e.b[blen-1] = '"'
   403  			e.e.encWr.writeb(e.b[:blen])
   404  		} else {
   405  			e.e.encWr.writeb(strconv.AppendInt(e.b[:0], v, 10))
   406  		}
   407  		return
   408  	}
   409  
   410  	if v < 0 {
   411  		e.encodeUint(true, quotes, uint64(-v))
   412  	} else {
   413  		e.encodeUint(false, quotes, uint64(v))
   414  	}
   415  }
   416  
   417  func (e *jsonEncDriver) EncodeUint(v uint64) {
   418  	quotes := e.is == 'A' || e.is == 'L' && v > 1<<53 ||
   419  		(e.ks && e.e.c == containerMapKey)
   420  
   421  	if cpu32Bit {
   422  		// use strconv directly, as optimized encodeUint only works on 64-bit alone
   423  		if quotes {
   424  			blen := 2 + len(strconv.AppendUint(e.b[1:1], v, 10))
   425  			e.b[0] = '"'
   426  			e.b[blen-1] = '"'
   427  			e.e.encWr.writeb(e.b[:blen])
   428  		} else {
   429  			e.e.encWr.writeb(strconv.AppendUint(e.b[:0], v, 10))
   430  		}
   431  		return
   432  	}
   433  
   434  	e.encodeUint(false, quotes, v)
   435  }
   436  
   437  func (e *jsonEncDriver) EncodeString(v string) {
   438  	if e.h.StringToRaw {
   439  		e.EncodeStringBytesRaw(bytesView(v))
   440  		return
   441  	}
   442  	e.quoteStr(v)
   443  }
   444  
   445  func (e *jsonEncDriver) EncodeStringBytesRaw(v []byte) {
   446  	// if encoding raw bytes and RawBytesExt is configured, use it to encode
   447  	if v == nil {
   448  		e.EncodeNil()
   449  		return
   450  	}
   451  
   452  	if e.rawext {
   453  		iv := e.h.RawBytesExt.ConvertExt(v)
   454  		if iv == nil {
   455  			e.EncodeNil()
   456  		} else {
   457  			e.e.encode(iv)
   458  		}
   459  		return
   460  	}
   461  
   462  	slen := base64.StdEncoding.EncodedLen(len(v)) + 2
   463  
   464  	// bs := e.e.blist.check(*e.buf, n)[:slen]
   465  	// *e.buf = bs
   466  
   467  	bs := e.e.blist.peek(slen, false)
   468  	bs = bs[:slen]
   469  
   470  	base64.StdEncoding.Encode(bs[1:], v)
   471  	bs[len(bs)-1] = '"'
   472  	bs[0] = '"'
   473  	e.e.encWr.writeb(bs)
   474  }
   475  
   476  // indent is done as below:
   477  //   - newline and indent are added before each mapKey or arrayElem
   478  //   - newline and indent are added before each ending,
   479  //     except there was no entry (so we can have {} or [])
   480  
   481  func (e *jsonEncDriver) WriteArrayStart(length int) {
   482  	if e.d {
   483  		e.dl++
   484  	}
   485  	e.e.encWr.writen1('[')
   486  }
   487  
   488  func (e *jsonEncDriver) WriteArrayEnd() {
   489  	if e.d {
   490  		e.dl--
   491  		e.writeIndent()
   492  	}
   493  	e.e.encWr.writen1(']')
   494  }
   495  
   496  func (e *jsonEncDriver) WriteMapStart(length int) {
   497  	if e.d {
   498  		e.dl++
   499  	}
   500  	e.e.encWr.writen1('{')
   501  }
   502  
   503  func (e *jsonEncDriver) WriteMapEnd() {
   504  	if e.d {
   505  		e.dl--
   506  		if e.e.c != containerMapStart {
   507  			e.writeIndent()
   508  		}
   509  	}
   510  	e.e.encWr.writen1('}')
   511  }
   512  
   513  func (e *jsonEncDriver) quoteStr(s string) {
   514  	// adapted from std pkg encoding/json
   515  	const hex = "0123456789abcdef"
   516  	w := e.e.w()
   517  	w.writen1('"')
   518  	var i, start uint
   519  	for i < uint(len(s)) {
   520  		// encode all bytes < 0x20 (except \r, \n).
   521  		// also encode < > & to prevent security holes when served to some browsers.
   522  
   523  		// We optimize for ascii, by assumining that most characters are in the BMP
   524  		// and natively consumed by json without much computation.
   525  
   526  		// if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
   527  		// if (htmlasis && jsonCharSafeSet.isset(b)) || jsonCharHtmlSafeSet.isset(b) {
   528  		if e.s.isset(s[i]) {
   529  			i++
   530  			continue
   531  		}
   532  		// b := s[i]
   533  		if s[i] < utf8.RuneSelf {
   534  			if start < i {
   535  				w.writestr(s[start:i])
   536  			}
   537  			switch s[i] {
   538  			case '\\', '"':
   539  				w.writen2('\\', s[i])
   540  			case '\n':
   541  				w.writen2('\\', 'n')
   542  			case '\r':
   543  				w.writen2('\\', 'r')
   544  			case '\b':
   545  				w.writen2('\\', 'b')
   546  			case '\f':
   547  				w.writen2('\\', 'f')
   548  			case '\t':
   549  				w.writen2('\\', 't')
   550  			default:
   551  				w.writestr(`\u00`)
   552  				w.writen2(hex[s[i]>>4], hex[s[i]&0xF])
   553  			}
   554  			i++
   555  			start = i
   556  			continue
   557  		}
   558  		c, size := utf8.DecodeRuneInString(s[i:])
   559  		if c == utf8.RuneError && size == 1 { // meaning invalid encoding (so output as-is)
   560  			if start < i {
   561  				w.writestr(s[start:i])
   562  			}
   563  			w.writestr(`\uFFFD`)
   564  			i++
   565  			start = i
   566  			continue
   567  		}
   568  		// U+2028 is LINE SEPARATOR. U+2029 is PARAGRAPH SEPARATOR.
   569  		// Both technically valid JSON, but bomb on JSONP, so fix here *unconditionally*.
   570  		if jsonEscapeMultiByteUnicodeSep && (c == '\u2028' || c == '\u2029') {
   571  			if start < i {
   572  				w.writestr(s[start:i])
   573  			}
   574  			w.writestr(`\u202`)
   575  			w.writen1(hex[c&0xF])
   576  			i += uint(size)
   577  			start = i
   578  			continue
   579  		}
   580  		i += uint(size)
   581  	}
   582  	if start < uint(len(s)) {
   583  		w.writestr(s[start:])
   584  	}
   585  	w.writen1('"')
   586  }
   587  
   588  func (e *jsonEncDriver) atEndOfEncode() {
   589  	if e.h.TermWhitespace {
   590  		var c byte = ' ' // default is that scalar is written, so output space
   591  		if e.e.c != 0 {
   592  			c = '\n' // for containers (map/list), output a newline
   593  		}
   594  		e.e.encWr.writen1(c)
   595  	}
   596  }
   597  
   598  // ----------
   599  
   600  type jsonDecState struct {
   601  	rawext bool // rawext configured on the handle
   602  
   603  	tok  uint8   // used to store the token read right after skipWhiteSpace
   604  	_    bool    // found null
   605  	_    byte    // padding
   606  	bstr [4]byte // scratch used for string \UXXX parsing
   607  
   608  	// scratch buffer used for base64 decoding (DecodeBytes in reuseBuf mode),
   609  	// or reading doubleQuoted string (DecodeStringAsBytes, DecodeNaked)
   610  	buf *[]byte
   611  }
   612  
   613  func (x jsonDecState) captureState() interface{}   { return x }
   614  func (x *jsonDecState) restoreState(v interface{}) { *x = v.(jsonDecState) }
   615  
   616  type jsonDecDriver struct {
   617  	noBuiltInTypes
   618  	decDriverNoopNumberHelper
   619  	h *JsonHandle
   620  
   621  	jsonDecState
   622  
   623  	// se  interfaceExtWrapper
   624  
   625  	// ---- cpu cache line boundary?
   626  
   627  	d Decoder
   628  }
   629  
   630  func (d *jsonDecDriver) descBd() (s string) { panic("descBd unsupported") }
   631  
   632  func (d *jsonDecDriver) decoder() *Decoder {
   633  	return &d.d
   634  }
   635  
   636  func (d *jsonDecDriver) ReadMapStart() int {
   637  	d.advance()
   638  	if d.tok == 'n' {
   639  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
   640  		return containerLenNil
   641  	}
   642  	if d.tok != '{' {
   643  		d.d.errorf("read map - expect char '%c' but got char '%c'", '{', d.tok)
   644  	}
   645  	d.tok = 0
   646  	return containerLenUnknown
   647  }
   648  
   649  func (d *jsonDecDriver) ReadArrayStart() int {
   650  	d.advance()
   651  	if d.tok == 'n' {
   652  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
   653  		return containerLenNil
   654  	}
   655  	if d.tok != '[' {
   656  		d.d.errorf("read array - expect char '%c' but got char '%c'", '[', d.tok)
   657  	}
   658  	d.tok = 0
   659  	return containerLenUnknown
   660  }
   661  
   662  // MARKER:
   663  // We attempted making sure CheckBreak can be inlined, by moving the skipWhitespace
   664  // call to an explicit (noinline) function call.
   665  // However, this forces CheckBreak to always incur a function call if there was whitespace,
   666  // with no clear benefit.
   667  
   668  func (d *jsonDecDriver) CheckBreak() bool {
   669  	d.advance()
   670  	return d.tok == '}' || d.tok == ']'
   671  }
   672  
   673  func (d *jsonDecDriver) ReadArrayElem() {
   674  	const xc uint8 = ','
   675  	if d.d.c != containerArrayStart {
   676  		d.advance()
   677  		if d.tok != xc {
   678  			d.readDelimError(xc)
   679  		}
   680  		d.tok = 0
   681  	}
   682  }
   683  
   684  func (d *jsonDecDriver) ReadArrayEnd() {
   685  	const xc uint8 = ']'
   686  	d.advance()
   687  	if d.tok != xc {
   688  		d.readDelimError(xc)
   689  	}
   690  	d.tok = 0
   691  }
   692  
   693  func (d *jsonDecDriver) ReadMapElemKey() {
   694  	const xc uint8 = ','
   695  	if d.d.c != containerMapStart {
   696  		d.advance()
   697  		if d.tok != xc {
   698  			d.readDelimError(xc)
   699  		}
   700  		d.tok = 0
   701  	}
   702  }
   703  
   704  func (d *jsonDecDriver) ReadMapElemValue() {
   705  	const xc uint8 = ':'
   706  	d.advance()
   707  	if d.tok != xc {
   708  		d.readDelimError(xc)
   709  	}
   710  	d.tok = 0
   711  }
   712  
   713  func (d *jsonDecDriver) ReadMapEnd() {
   714  	const xc uint8 = '}'
   715  	d.advance()
   716  	if d.tok != xc {
   717  		d.readDelimError(xc)
   718  	}
   719  	d.tok = 0
   720  }
   721  
   722  func (d *jsonDecDriver) readDelimError(xc uint8) {
   723  	d.d.errorf("read json delimiter - expect char '%c' but got char '%c'", xc, d.tok)
   724  }
   725  
   726  // MARKER: checkLit takes the readn(3|4) result as a parameter so they can be inlined.
   727  // We pass the array directly to errorf, as passing slice pushes past inlining threshold,
   728  // and passing slice also might cause allocation of the bs array on the heap.
   729  
   730  func (d *jsonDecDriver) checkLit3(got, expect [3]byte) {
   731  	d.tok = 0
   732  	if jsonValidateSymbols && got != expect {
   733  		d.d.errorf("expecting %s: got %s", expect, got)
   734  	}
   735  }
   736  
   737  func (d *jsonDecDriver) checkLit4(got, expect [4]byte) {
   738  	d.tok = 0
   739  	if jsonValidateSymbols && got != expect {
   740  		d.d.errorf("expecting %s: got %s", expect, got)
   741  	}
   742  }
   743  
   744  func (d *jsonDecDriver) skipWhitespace() {
   745  	d.tok = d.d.decRd.skipWhitespace()
   746  }
   747  
   748  func (d *jsonDecDriver) advance() {
   749  	if d.tok == 0 {
   750  		d.skipWhitespace()
   751  	}
   752  }
   753  
   754  func (d *jsonDecDriver) nextValueBytes(v []byte) []byte {
   755  	v, cursor := d.nextValueBytesR(v)
   756  	decNextValueBytesHelper{d: &d.d}.bytesRdV(&v, cursor)
   757  	return v
   758  }
   759  
   760  func (d *jsonDecDriver) nextValueBytesR(v0 []byte) (v []byte, cursor uint) {
   761  	v = v0
   762  	var h = decNextValueBytesHelper{d: &d.d}
   763  	dr := &d.d.decRd
   764  
   765  	consumeString := func() {
   766  	TOP:
   767  		bs := dr.jsonReadAsisChars()
   768  		h.appendN(&v, bs...)
   769  		if bs[len(bs)-1] != '"' {
   770  			// last char is '\', so consume next one and try again
   771  			h.append1(&v, dr.readn1())
   772  			goto TOP
   773  		}
   774  	}
   775  
   776  	d.advance()           // ignore leading whitespace
   777  	cursor = d.d.rb.c - 1 // cursor starts just before non-whitespace token
   778  
   779  	switch d.tok {
   780  	default:
   781  		h.appendN(&v, dr.jsonReadNum()...)
   782  	case 'n':
   783  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
   784  		h.appendS(&v, jsonLits[jsonLitN:jsonLitN+4])
   785  	case 'f':
   786  		d.checkLit4([4]byte{'a', 'l', 's', 'e'}, d.d.decRd.readn4())
   787  		h.appendS(&v, jsonLits[jsonLitF:jsonLitF+5])
   788  	case 't':
   789  		d.checkLit3([3]byte{'r', 'u', 'e'}, d.d.decRd.readn3())
   790  		h.appendS(&v, jsonLits[jsonLitT:jsonLitT+4])
   791  	case '"':
   792  		h.append1(&v, '"')
   793  		consumeString()
   794  	case '{', '[':
   795  		var elem struct{}
   796  		var stack []struct{}
   797  
   798  		stack = append(stack, elem)
   799  
   800  		h.append1(&v, d.tok)
   801  
   802  		for len(stack) != 0 {
   803  			c := dr.readn1()
   804  			h.append1(&v, c)
   805  			switch c {
   806  			case '"':
   807  				consumeString()
   808  			case '{', '[':
   809  				stack = append(stack, elem)
   810  			case '}', ']':
   811  				stack = stack[:len(stack)-1]
   812  			}
   813  		}
   814  	}
   815  	d.tok = 0
   816  	return
   817  }
   818  
   819  func (d *jsonDecDriver) TryNil() bool {
   820  	d.advance()
   821  	// we shouldn't try to see if quoted "null" was here, right?
   822  	// only the plain string: `null` denotes a nil (ie not quotes)
   823  	if d.tok == 'n' {
   824  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
   825  		return true
   826  	}
   827  	return false
   828  }
   829  
   830  func (d *jsonDecDriver) DecodeBool() (v bool) {
   831  	d.advance()
   832  	// bool can be in quotes if and only if it's a map key
   833  	fquot := d.d.c == containerMapKey && d.tok == '"'
   834  	if fquot {
   835  		d.tok = d.d.decRd.readn1()
   836  	}
   837  	switch d.tok {
   838  	case 'f':
   839  		d.checkLit4([4]byte{'a', 'l', 's', 'e'}, d.d.decRd.readn4())
   840  		// v = false
   841  	case 't':
   842  		d.checkLit3([3]byte{'r', 'u', 'e'}, d.d.decRd.readn3())
   843  		v = true
   844  	case 'n':
   845  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
   846  		// v = false
   847  	default:
   848  		d.d.errorf("decode bool: got first char %c", d.tok)
   849  		// v = false // "unreachable"
   850  	}
   851  	if fquot {
   852  		d.d.decRd.readn1()
   853  	}
   854  	return
   855  }
   856  
   857  func (d *jsonDecDriver) DecodeTime() (t time.Time) {
   858  	// read string, and pass the string into json.unmarshal
   859  	d.advance()
   860  	if d.tok == 'n' {
   861  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
   862  		return
   863  	}
   864  	d.ensureReadingString()
   865  	bs := d.readUnescapedString()
   866  	t, err := time.Parse(time.RFC3339, stringView(bs))
   867  	d.d.onerror(err)
   868  	return
   869  }
   870  
   871  func (d *jsonDecDriver) ContainerType() (vt valueType) {
   872  	// check container type by checking the first char
   873  	d.advance()
   874  
   875  	// optimize this, so we don't do 4 checks but do one computation.
   876  	// return jsonContainerSet[d.tok]
   877  
   878  	// ContainerType is mostly called for Map and Array,
   879  	// so this conditional is good enough (max 2 checks typically)
   880  	if d.tok == '{' {
   881  		return valueTypeMap
   882  	} else if d.tok == '[' {
   883  		return valueTypeArray
   884  	} else if d.tok == 'n' {
   885  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
   886  		return valueTypeNil
   887  	} else if d.tok == '"' {
   888  		return valueTypeString
   889  	}
   890  	return valueTypeUnset
   891  }
   892  
   893  func (d *jsonDecDriver) decNumBytes() (bs []byte) {
   894  	d.advance()
   895  	dr := &d.d.decRd
   896  	if d.tok == '"' {
   897  		bs = dr.readUntil('"')
   898  	} else if d.tok == 'n' {
   899  		d.checkLit3([3]byte{'u', 'l', 'l'}, dr.readn3())
   900  	} else {
   901  		if jsonManualInlineDecRdInHotZones {
   902  			if dr.bytes {
   903  				bs = dr.rb.jsonReadNum()
   904  			} else {
   905  				bs = dr.ri.jsonReadNum()
   906  			}
   907  		} else {
   908  			bs = dr.jsonReadNum()
   909  		}
   910  	}
   911  	d.tok = 0
   912  	return
   913  }
   914  
   915  func (d *jsonDecDriver) DecodeUint64() (u uint64) {
   916  	b := d.decNumBytes()
   917  	u, neg, ok := parseInteger_bytes(b)
   918  	if neg {
   919  		d.d.errorf("negative number cannot be decoded as uint64")
   920  	}
   921  	if !ok {
   922  		d.d.onerror(strconvParseErr(b, "ParseUint"))
   923  	}
   924  	return
   925  }
   926  
   927  func (d *jsonDecDriver) DecodeInt64() (v int64) {
   928  	b := d.decNumBytes()
   929  	u, neg, ok := parseInteger_bytes(b)
   930  	if !ok {
   931  		d.d.onerror(strconvParseErr(b, "ParseInt"))
   932  	}
   933  	if chkOvf.Uint2Int(u, neg) {
   934  		d.d.errorf("overflow decoding number from %s", b)
   935  	}
   936  	if neg {
   937  		v = -int64(u)
   938  	} else {
   939  		v = int64(u)
   940  	}
   941  	return
   942  }
   943  
   944  func (d *jsonDecDriver) DecodeFloat64() (f float64) {
   945  	var err error
   946  	bs := d.decNumBytes()
   947  	if len(bs) == 0 {
   948  		return
   949  	}
   950  	f, err = parseFloat64(bs)
   951  	d.d.onerror(err)
   952  	return
   953  }
   954  
   955  func (d *jsonDecDriver) DecodeFloat32() (f float32) {
   956  	var err error
   957  	bs := d.decNumBytes()
   958  	if len(bs) == 0 {
   959  		return
   960  	}
   961  	f, err = parseFloat32(bs)
   962  	d.d.onerror(err)
   963  	return
   964  }
   965  
   966  func (d *jsonDecDriver) DecodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) {
   967  	d.advance()
   968  	if d.tok == 'n' {
   969  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
   970  		return
   971  	}
   972  	if ext == nil {
   973  		re := rv.(*RawExt)
   974  		re.Tag = xtag
   975  		d.d.decode(&re.Value)
   976  	} else if ext == SelfExt {
   977  		d.d.decodeValue(baseRV(rv), d.h.fnNoExt(basetype))
   978  	} else {
   979  		d.d.interfaceExtConvertAndDecode(rv, ext)
   980  	}
   981  }
   982  
   983  func (d *jsonDecDriver) decBytesFromArray(bs []byte) []byte {
   984  	if bs != nil {
   985  		bs = bs[:0]
   986  	}
   987  	d.tok = 0
   988  	bs = append(bs, uint8(d.DecodeUint64()))
   989  	d.tok = d.d.decRd.skipWhitespace() // skip(&whitespaceCharBitset)
   990  	for d.tok != ']' {
   991  		if d.tok != ',' {
   992  			d.d.errorf("read array element - expect char '%c' but got char '%c'", ',', d.tok)
   993  		}
   994  		d.tok = 0
   995  		bs = append(bs, uint8(chkOvf.UintV(d.DecodeUint64(), 8)))
   996  		d.tok = d.d.decRd.skipWhitespace() // skip(&whitespaceCharBitset)
   997  	}
   998  	d.tok = 0
   999  	return bs
  1000  }
  1001  
  1002  func (d *jsonDecDriver) DecodeBytes(bs []byte) (bsOut []byte) {
  1003  	d.d.decByteState = decByteStateNone
  1004  	d.advance()
  1005  	if d.tok == 'n' {
  1006  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
  1007  		return nil
  1008  	}
  1009  	// if decoding into raw bytes, and the RawBytesExt is configured, use it to decode.
  1010  	if d.rawext {
  1011  		bsOut = bs
  1012  		d.d.interfaceExtConvertAndDecode(&bsOut, d.h.RawBytesExt)
  1013  		return
  1014  	}
  1015  	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
  1016  	if d.tok == '[' {
  1017  		// bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
  1018  		if bs == nil {
  1019  			d.d.decByteState = decByteStateReuseBuf
  1020  			bs = d.d.b[:]
  1021  		}
  1022  		return d.decBytesFromArray(bs)
  1023  	}
  1024  
  1025  	// base64 encodes []byte{} as "", and we encode nil []byte as null.
  1026  	// Consequently, base64 should decode null as a nil []byte, and "" as an empty []byte{}.
  1027  
  1028  	d.ensureReadingString()
  1029  	bs1 := d.readUnescapedString()
  1030  	slen := base64.StdEncoding.DecodedLen(len(bs1))
  1031  	if slen == 0 {
  1032  		bsOut = []byte{}
  1033  	} else if slen <= cap(bs) {
  1034  		bsOut = bs[:slen]
  1035  	} else if bs == nil {
  1036  		d.d.decByteState = decByteStateReuseBuf
  1037  		bsOut = d.d.blist.check(*d.buf, slen)
  1038  		bsOut = bsOut[:slen]
  1039  		*d.buf = bsOut
  1040  	} else {
  1041  		bsOut = make([]byte, slen)
  1042  	}
  1043  	slen2, err := base64.StdEncoding.Decode(bsOut, bs1)
  1044  	if err != nil {
  1045  		d.d.errorf("error decoding base64 binary '%s': %v", bs1, err)
  1046  	}
  1047  	if slen != slen2 {
  1048  		bsOut = bsOut[:slen2]
  1049  	}
  1050  	return
  1051  }
  1052  
  1053  func (d *jsonDecDriver) DecodeStringAsBytes() (s []byte) {
  1054  	d.d.decByteState = decByteStateNone
  1055  	d.advance()
  1056  
  1057  	// common case - hoist outside the switch statement
  1058  	if d.tok == '"' {
  1059  		return d.dblQuoteStringAsBytes()
  1060  	}
  1061  
  1062  	// handle non-string scalar: null, true, false or a number
  1063  	switch d.tok {
  1064  	case 'n':
  1065  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
  1066  		return nil // []byte{}
  1067  	case 'f':
  1068  		d.checkLit4([4]byte{'a', 'l', 's', 'e'}, d.d.decRd.readn4())
  1069  		return jsonLitb[jsonLitF : jsonLitF+5]
  1070  	case 't':
  1071  		d.checkLit3([3]byte{'r', 'u', 'e'}, d.d.decRd.readn3())
  1072  		return jsonLitb[jsonLitT : jsonLitT+4]
  1073  	default:
  1074  		// try to parse a valid number
  1075  		d.tok = 0
  1076  		return d.d.decRd.jsonReadNum()
  1077  	}
  1078  }
  1079  
  1080  func (d *jsonDecDriver) ensureReadingString() {
  1081  	if d.tok != '"' {
  1082  		d.d.errorf("expecting string starting with '\"'; got '%c'", d.tok)
  1083  	}
  1084  }
  1085  
  1086  func (d *jsonDecDriver) readUnescapedString() (bs []byte) {
  1087  	// d.ensureReadingString()
  1088  	bs = d.d.decRd.readUntil('"')
  1089  	d.tok = 0
  1090  	return
  1091  }
  1092  
  1093  func (d *jsonDecDriver) dblQuoteStringAsBytes() (buf []byte) {
  1094  	checkUtf8 := d.h.ValidateUnicode
  1095  	d.d.decByteState = decByteStateNone
  1096  	// use a local buf variable, so we don't do pointer chasing within loop
  1097  	buf = (*d.buf)[:0]
  1098  	dr := &d.d.decRd
  1099  	d.tok = 0
  1100  
  1101  	var bs []byte
  1102  	var c byte
  1103  	var firstTime bool = true
  1104  
  1105  	for {
  1106  		if firstTime {
  1107  			firstTime = false
  1108  			if dr.bytes {
  1109  				bs = dr.rb.jsonReadAsisChars()
  1110  				if bs[len(bs)-1] == '"' {
  1111  					d.d.decByteState = decByteStateZerocopy
  1112  					return bs[:len(bs)-1]
  1113  				}
  1114  				goto APPEND
  1115  			}
  1116  		}
  1117  
  1118  		if jsonManualInlineDecRdInHotZones {
  1119  			if dr.bytes {
  1120  				bs = dr.rb.jsonReadAsisChars()
  1121  			} else {
  1122  				bs = dr.ri.jsonReadAsisChars()
  1123  			}
  1124  		} else {
  1125  			bs = dr.jsonReadAsisChars()
  1126  		}
  1127  
  1128  	APPEND:
  1129  		_ = bs[0] // bounds check hint - slice must be > 0 elements
  1130  		buf = append(buf, bs[:len(bs)-1]...)
  1131  		c = bs[len(bs)-1]
  1132  
  1133  		if c == '"' {
  1134  			break
  1135  		}
  1136  
  1137  		// c is now '\'
  1138  		c = dr.readn1()
  1139  
  1140  		switch c {
  1141  		case '"', '\\', '/', '\'':
  1142  			buf = append(buf, c)
  1143  		case 'b':
  1144  			buf = append(buf, '\b')
  1145  		case 'f':
  1146  			buf = append(buf, '\f')
  1147  		case 'n':
  1148  			buf = append(buf, '\n')
  1149  		case 'r':
  1150  			buf = append(buf, '\r')
  1151  		case 't':
  1152  			buf = append(buf, '\t')
  1153  		case 'u':
  1154  			rr := d.appendStringAsBytesSlashU()
  1155  			if checkUtf8 && rr == unicode.ReplacementChar {
  1156  				d.d.errorf("invalid UTF-8 character found after: %s", buf)
  1157  			}
  1158  			buf = append(buf, d.bstr[:utf8.EncodeRune(d.bstr[:], rr)]...)
  1159  		default:
  1160  			*d.buf = buf
  1161  			d.d.errorf("unsupported escaped value: %c", c)
  1162  		}
  1163  	}
  1164  	*d.buf = buf
  1165  	d.d.decByteState = decByteStateReuseBuf
  1166  	return
  1167  }
  1168  
  1169  func (d *jsonDecDriver) appendStringAsBytesSlashU() (r rune) {
  1170  	var rr uint32
  1171  	var csu [2]byte
  1172  	var cs [4]byte = d.d.decRd.readn4()
  1173  	if rr = jsonSlashURune(cs); rr == unicode.ReplacementChar {
  1174  		return unicode.ReplacementChar
  1175  	}
  1176  	r = rune(rr)
  1177  	if utf16.IsSurrogate(r) {
  1178  		csu = d.d.decRd.readn2()
  1179  		cs = d.d.decRd.readn4()
  1180  		if csu[0] == '\\' && csu[1] == 'u' {
  1181  			if rr = jsonSlashURune(cs); rr == unicode.ReplacementChar {
  1182  				return unicode.ReplacementChar
  1183  			}
  1184  			return utf16.DecodeRune(r, rune(rr))
  1185  		}
  1186  		return unicode.ReplacementChar
  1187  	}
  1188  	return
  1189  }
  1190  
  1191  func jsonSlashURune(cs [4]byte) (rr uint32) {
  1192  	for _, c := range cs {
  1193  		// best to use explicit if-else
  1194  		// - not a table, etc which involve memory loads, array lookup with bounds checks, etc
  1195  		if c >= '0' && c <= '9' {
  1196  			rr = rr*16 + uint32(c-jsonU4Chk2)
  1197  		} else if c >= 'a' && c <= 'f' {
  1198  			rr = rr*16 + uint32(c-jsonU4Chk1)
  1199  		} else if c >= 'A' && c <= 'F' {
  1200  			rr = rr*16 + uint32(c-jsonU4Chk0)
  1201  		} else {
  1202  			return unicode.ReplacementChar
  1203  		}
  1204  	}
  1205  	return
  1206  }
  1207  
  1208  func (d *jsonDecDriver) nakedNum(z *fauxUnion, bs []byte) (err error) {
  1209  	// Note: nakedNum is NEVER called with a zero-length []byte
  1210  	if d.h.PreferFloat {
  1211  		z.v = valueTypeFloat
  1212  		z.f, err = parseFloat64(bs)
  1213  	} else {
  1214  		err = parseNumber(bs, z, d.h.SignedInteger)
  1215  	}
  1216  	return
  1217  }
  1218  
  1219  func (d *jsonDecDriver) DecodeNaked() {
  1220  	z := d.d.naked()
  1221  
  1222  	d.advance()
  1223  	var bs []byte
  1224  	switch d.tok {
  1225  	case 'n':
  1226  		d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
  1227  		z.v = valueTypeNil
  1228  	case 'f':
  1229  		d.checkLit4([4]byte{'a', 'l', 's', 'e'}, d.d.decRd.readn4())
  1230  		z.v = valueTypeBool
  1231  		z.b = false
  1232  	case 't':
  1233  		d.checkLit3([3]byte{'r', 'u', 'e'}, d.d.decRd.readn3())
  1234  		z.v = valueTypeBool
  1235  		z.b = true
  1236  	case '{':
  1237  		z.v = valueTypeMap // don't consume. kInterfaceNaked will call ReadMapStart
  1238  	case '[':
  1239  		z.v = valueTypeArray // don't consume. kInterfaceNaked will call ReadArrayStart
  1240  	case '"':
  1241  		// if a string, and MapKeyAsString, then try to decode it as a bool or number first
  1242  		bs = d.dblQuoteStringAsBytes()
  1243  		if jsonNakedBoolNullInQuotedStr &&
  1244  			d.h.MapKeyAsString && len(bs) > 0 && d.d.c == containerMapKey {
  1245  			switch string(bs) {
  1246  			// case "null": // nil is never quoted
  1247  			// 	z.v = valueTypeNil
  1248  			case "true":
  1249  				z.v = valueTypeBool
  1250  				z.b = true
  1251  			case "false":
  1252  				z.v = valueTypeBool
  1253  				z.b = false
  1254  			default:
  1255  				// check if a number: float, int or uint
  1256  				if err := d.nakedNum(z, bs); err != nil {
  1257  					z.v = valueTypeString
  1258  					z.s = d.d.stringZC(bs)
  1259  				}
  1260  			}
  1261  		} else {
  1262  			z.v = valueTypeString
  1263  			z.s = d.d.stringZC(bs)
  1264  		}
  1265  	default: // number
  1266  		bs = d.d.decRd.jsonReadNum()
  1267  		d.tok = 0
  1268  		if len(bs) == 0 {
  1269  			d.d.errorf("decode number from empty string")
  1270  		}
  1271  		if err := d.nakedNum(z, bs); err != nil {
  1272  			d.d.errorf("decode number from %s: %v", bs, err)
  1273  		}
  1274  	}
  1275  }
  1276  
  1277  //----------------------
  1278  
  1279  // JsonHandle is a handle for JSON encoding format.
  1280  //
  1281  // Json is comprehensively supported:
  1282  //   - decodes numbers into interface{} as int, uint or float64
  1283  //     based on how the number looks and some config parameters e.g. PreferFloat, SignedInt, etc.
  1284  //   - decode integers from float formatted numbers e.g. 1.27e+8
  1285  //   - decode any json value (numbers, bool, etc) from quoted strings
  1286  //   - configurable way to encode/decode []byte .
  1287  //     by default, encodes and decodes []byte using base64 Std Encoding
  1288  //   - UTF-8 support for encoding and decoding
  1289  //
  1290  // It has better performance than the json library in the standard library,
  1291  // by leveraging the performance improvements of the codec library.
  1292  //
  1293  // In addition, it doesn't read more bytes than necessary during a decode, which allows
  1294  // reading multiple values from a stream containing json and non-json content.
  1295  // For example, a user can read a json value, then a cbor value, then a msgpack value,
  1296  // all from the same stream in sequence.
  1297  //
  1298  // Note that, when decoding quoted strings, invalid UTF-8 or invalid UTF-16 surrogate pairs are
  1299  // not treated as an error. Instead, they are replaced by the Unicode replacement character U+FFFD.
  1300  //
  1301  // Note also that the float values for NaN, +Inf or -Inf are encoded as null,
  1302  // as suggested by NOTE 4 of the ECMA-262 ECMAScript Language Specification 5.1 edition.
  1303  // see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf .
  1304  //
  1305  // Note the following behaviour differences vs std-library encoding/json package:
  1306  //   - struct field names matched in case-sensitive manner
  1307  type JsonHandle struct {
  1308  	textEncodingType
  1309  	BasicHandle
  1310  
  1311  	// Indent indicates how a value is encoded.
  1312  	//   - If positive, indent by that number of spaces.
  1313  	//   - If negative, indent by that number of tabs.
  1314  	Indent int8
  1315  
  1316  	// IntegerAsString controls how integers (signed and unsigned) are encoded.
  1317  	//
  1318  	// Per the JSON Spec, JSON numbers are 64-bit floating point numbers.
  1319  	// Consequently, integers > 2^53 cannot be represented as a JSON number without losing precision.
  1320  	// This can be mitigated by configuring how to encode integers.
  1321  	//
  1322  	// IntegerAsString interpretes the following values:
  1323  	//   - if 'L', then encode integers > 2^53 as a json string.
  1324  	//   - if 'A', then encode all integers as a json string
  1325  	//             containing the exact integer representation as a decimal.
  1326  	//   - else    encode all integers as a json number (default)
  1327  	IntegerAsString byte
  1328  
  1329  	// HTMLCharsAsIs controls how to encode some special characters to html: < > &
  1330  	//
  1331  	// By default, we encode them as \uXXX
  1332  	// to prevent security holes when served from some browsers.
  1333  	HTMLCharsAsIs bool
  1334  
  1335  	// PreferFloat says that we will default to decoding a number as a float.
  1336  	// If not set, we will examine the characters of the number and decode as an
  1337  	// integer type if it doesn't have any of the characters [.eE].
  1338  	PreferFloat bool
  1339  
  1340  	// TermWhitespace says that we add a whitespace character
  1341  	// at the end of an encoding.
  1342  	//
  1343  	// The whitespace is important, especially if using numbers in a context
  1344  	// where multiple items are written to a stream.
  1345  	TermWhitespace bool
  1346  
  1347  	// MapKeyAsString says to encode all map keys as strings.
  1348  	//
  1349  	// Use this to enforce strict json output.
  1350  	// The only caveat is that nil value is ALWAYS written as null (never as "null")
  1351  	MapKeyAsString bool
  1352  
  1353  	// _ uint64 // padding (cache line)
  1354  
  1355  	// Note: below, we store hardly-used items e.g. RawBytesExt.
  1356  	// These values below may straddle a cache line, but they are hardly-used,
  1357  	// so shouldn't contribute to false-sharing except in rare cases.
  1358  
  1359  	// RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way.
  1360  	// If not configured, raw bytes are encoded to/from base64 text.
  1361  	RawBytesExt InterfaceExt
  1362  }
  1363  
  1364  func (h *JsonHandle) isJson() bool { return true }
  1365  
  1366  // Name returns the name of the handle: json
  1367  func (h *JsonHandle) Name() string { return "json" }
  1368  
  1369  func (h *JsonHandle) desc(bd byte) string { return string(bd) }
  1370  
  1371  func (h *JsonHandle) typical() bool {
  1372  	return h.Indent == 0 && !h.MapKeyAsString && h.IntegerAsString != 'A' && h.IntegerAsString != 'L'
  1373  }
  1374  
  1375  func (h *JsonHandle) newEncDriver() encDriver {
  1376  	var e = &jsonEncDriver{h: h}
  1377  	// var x []byte
  1378  	// e.buf = &x
  1379  	e.e.e = e
  1380  	e.e.js = true
  1381  	e.e.init(h)
  1382  	e.reset()
  1383  	return e
  1384  }
  1385  
  1386  func (h *JsonHandle) newDecDriver() decDriver {
  1387  	var d = &jsonDecDriver{h: h}
  1388  	var x []byte
  1389  	d.buf = &x
  1390  	d.d.d = d
  1391  	d.d.js = true
  1392  	d.d.jsms = h.MapKeyAsString
  1393  	d.d.init(h)
  1394  	d.reset()
  1395  	return d
  1396  }
  1397  
  1398  func (e *jsonEncDriver) resetState() {
  1399  	e.dl = 0
  1400  }
  1401  
  1402  func (e *jsonEncDriver) reset() {
  1403  	e.resetState()
  1404  	// (htmlasis && jsonCharSafeSet.isset(b)) || jsonCharHtmlSafeSet.isset(b)
  1405  	// cache values from the handle
  1406  	e.typical = e.h.typical()
  1407  	if e.h.HTMLCharsAsIs {
  1408  		e.s = &jsonCharSafeSet
  1409  	} else {
  1410  		e.s = &jsonCharHtmlSafeSet
  1411  	}
  1412  	e.rawext = e.h.RawBytesExt != nil
  1413  	e.di = int8(e.h.Indent)
  1414  	e.d = e.h.Indent != 0
  1415  	e.ks = e.h.MapKeyAsString
  1416  	e.is = e.h.IntegerAsString
  1417  }
  1418  
  1419  func (d *jsonDecDriver) resetState() {
  1420  	*d.buf = d.d.blist.check(*d.buf, 256)
  1421  	d.tok = 0
  1422  }
  1423  
  1424  func (d *jsonDecDriver) reset() {
  1425  	d.resetState()
  1426  	d.rawext = d.h.RawBytesExt != nil
  1427  }
  1428  
  1429  func jsonFloatStrconvFmtPrec64(f float64) (fmt byte, prec int8) {
  1430  	fmt = 'f'
  1431  	prec = -1
  1432  	fbits := math.Float64bits(f)
  1433  	abs := math.Float64frombits(fbits &^ (1 << 63))
  1434  	if abs == 0 || abs == 1 {
  1435  		prec = 1
  1436  	} else if abs < 1e-6 || abs >= 1e21 {
  1437  		fmt = 'e'
  1438  	} else if noFrac64(fbits) {
  1439  		prec = 1
  1440  	}
  1441  	return
  1442  }
  1443  
  1444  func jsonFloatStrconvFmtPrec32(f float32) (fmt byte, prec int8) {
  1445  	fmt = 'f'
  1446  	prec = -1
  1447  	// directly handle Modf (to get fractions) and Abs (to get absolute)
  1448  	fbits := math.Float32bits(f)
  1449  	abs := math.Float32frombits(fbits &^ (1 << 31))
  1450  	if abs == 0 || abs == 1 {
  1451  		prec = 1
  1452  	} else if abs < 1e-6 || abs >= 1e21 {
  1453  		fmt = 'e'
  1454  	} else if noFrac32(fbits) {
  1455  		prec = 1
  1456  	}
  1457  	return
  1458  }
  1459  
  1460  var _ decDriverContainerTracker = (*jsonDecDriver)(nil)
  1461  var _ encDriverContainerTracker = (*jsonEncDriver)(nil)
  1462  var _ decDriver = (*jsonDecDriver)(nil)
  1463  var _ encDriver = (*jsonEncDriver)(nil)