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