37
const jsonLits = `"true"false"null"`
39
var jsonLitb = []byte(jsonLits)
47
const jsonEncodeUintSmallsString = "" +
48
"00010203040506070809" +
49
"10111213141516171819" +
50
"20212223242526272829" +
51
"30313233343536373839" +
52
"40414243444546474849" +
53
"50515253545556575859" +
54
"60616263646566676869" +
55
"70717273747576777879" +
56
"80818283848586878889" +
57
"90919293949596979899"
59
var jsonEncodeUintSmallsStringBytes = []byte(jsonEncodeUintSmallsString)
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
76
// jsonEscapeMultiByteUnicodeSep controls whether some unicode characters
77
// that are valid json but may bomb in some contexts are escaped during encoeing.
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
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
88
// jsonManualInlineDecRdInHotZones controls whether we manually inline some decReader calls.
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)
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
116
jsonSpacesOrTabsLen = 128
118
// jsonAlwaysReturnInternString = false
122
// jsonTabs and jsonSpaces are used as caches for indents
123
jsonTabs, jsonSpaces [jsonSpacesOrTabsLen]byte
125
jsonCharHtmlSafeSet bitset256
126
jsonCharSafeSet bitset256
131
for i = 0; i < jsonSpacesOrTabsLen; i++ {
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++ {
143
jsonCharSafeSet.set(i) // = true
145
jsonCharSafeSet.set(i)
146
jsonCharHtmlSafeSet.set(i)
153
type jsonEncState struct {
154
di int8 // indent per: if negative, use tabs
156
dl uint16 // indent level
159
func (x jsonEncState) captureState() interface{} { return x }
160
func (x *jsonEncState) restoreState(v interface{}) { *x = v.(jsonEncState) }
162
type jsonEncDriver struct {
166
// se interfaceExtWrapper
168
// ---- cpu cache line boundary?
171
ks bool // map key as string
172
is byte // integer as string
175
rawext bool // rawext configured on the handle
177
s *bitset256 // safe set for characters (taking h.HTMLAsIs into consideration)
179
// buf *[]byte // used mostly for encoding []byte
181
// scratch buffer for: encode time, numbers, etc
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.
197
func (e *jsonEncDriver) encoder() *Encoder { return &e.e }
199
func (e *jsonEncDriver) writeIndent() {
200
e.e.encWr.writen1('\n')
201
x := int(e.di) * int(e.dl)
204
for x > jsonSpacesOrTabsLen {
205
e.e.encWr.writeb(jsonTabs[:])
206
x -= jsonSpacesOrTabsLen
208
e.e.encWr.writeb(jsonTabs[:x])
210
for x > jsonSpacesOrTabsLen {
211
e.e.encWr.writeb(jsonSpaces[:])
212
x -= jsonSpacesOrTabsLen
214
e.e.encWr.writeb(jsonSpaces[:x])
218
func (e *jsonEncDriver) WriteArrayElem() {
219
if e.e.c != containerArrayStart {
220
e.e.encWr.writen1(',')
227
func (e *jsonEncDriver) WriteMapElemKey() {
228
if e.e.c != containerMapStart {
229
e.e.encWr.writen1(',')
236
func (e *jsonEncDriver) WriteMapElemValue() {
238
e.e.encWr.writen2(':', ' ')
240
e.e.encWr.writen1(':')
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.
248
e.e.encWr.writestr(jsonLits[jsonLitN : jsonLitN+4])
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)
259
b := fmtTime(t, time.RFC3339Nano, e.b[1:1])
261
e.e.encWr.writeb(e.b[:len(b)+2])
265
func (e *jsonEncDriver) EncodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) {
267
e.e.encodeValue(baseRV(rv), e.h.fnNoExt(basetype))
268
} else if v := ext.ConvertExt(rv); v == nil {
275
func (e *jsonEncDriver) EncodeRawExt(re *RawExt) {
276
// only encodes re.Value (never re.Data)
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]},
289
func (e *jsonEncDriver) EncodeBool(b bool) {
291
jsonEncBoolStrs[bool2int(e.ks && e.e.c == containerMapKey)%2][bool2int(b)%2])
294
// func (e *jsonEncDriver) EncodeBool(b bool) {
295
// if e.ks && e.e.c == containerMapKey {
297
// e.e.encWr.writestr(jsonLits[jsonLitT-1 : jsonLitT+5])
299
// e.e.encWr.writestr(jsonLits[jsonLitF-1 : jsonLitF+6])
303
// e.e.encWr.writestr(jsonLits[jsonLitT : jsonLitT+4])
305
// e.e.encWr.writestr(jsonLits[jsonLitF : jsonLitF+5])
310
func (e *jsonEncDriver) encodeFloat(f float64, bitsize, fmt byte, prec int8) {
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))))
317
e.e.encWr.writeb(e.b[:blen])
319
e.e.encWr.writeb(strconv.AppendFloat(e.b[:0], f, fmt, int(prec), int(bitsize)))
323
func (e *jsonEncDriver) EncodeFloat64(f float64) {
324
if math.IsNaN(f) || math.IsInf(f, 0) {
328
fmt, prec := jsonFloatStrconvFmtPrec64(f)
329
e.encodeFloat(f, 64, fmt, prec)
332
func (e *jsonEncDriver) EncodeFloat32(f float32) {
333
if math.IsNaN(float64(f)) || math.IsInf(float64(f), 0) {
337
fmt, prec := jsonFloatStrconvFmtPrec32(f)
338
e.encodeFloat(float64(f), 32, fmt, prec)
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.
345
// const smallsString = jsonEncodeUintSmallsString
346
var ss = jsonEncodeUintSmallsStringBytes
348
// typically, 19 or 20 bytes sufficient for decimal encoding a uint64
358
// u guaranteed to fit into a uint (as we are not 32bit OS)
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]
374
setByteAt(a, i, byteAt(ss, is+1))
375
// a[i] = smallsString[is+1]
378
setByteAt(a, i, byteAt(ss, is))
379
// a[i] = smallsString[is]
391
e.e.encWr.writeb(a[i:])
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)
400
blen := 2 + len(strconv.AppendInt(e.b[1:1], v, 10))
403
e.e.encWr.writeb(e.b[:blen])
405
e.e.encWr.writeb(strconv.AppendInt(e.b[:0], v, 10))
411
e.encodeUint(true, quotes, uint64(-v))
413
e.encodeUint(false, quotes, uint64(v))
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)
422
// use strconv directly, as optimized encodeUint only works on 64-bit alone
424
blen := 2 + len(strconv.AppendUint(e.b[1:1], v, 10))
427
e.e.encWr.writeb(e.b[:blen])
429
e.e.encWr.writeb(strconv.AppendUint(e.b[:0], v, 10))
434
e.encodeUint(false, quotes, v)
437
func (e *jsonEncDriver) EncodeString(v string) {
439
e.EncodeStringBytesRaw(bytesView(v))
445
func (e *jsonEncDriver) EncodeStringBytesRaw(v []byte) {
446
// if encoding raw bytes and RawBytesExt is configured, use it to encode
453
iv := e.h.RawBytesExt.ConvertExt(v)
462
slen := base64.StdEncoding.EncodedLen(len(v)) + 2
464
// bs := e.e.blist.check(*e.buf, n)[:slen]
467
bs := e.e.blist.peek(slen, false)
470
base64.StdEncoding.Encode(bs[1:], v)
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 [])
481
func (e *jsonEncDriver) WriteArrayStart(length int) {
485
e.e.encWr.writen1('[')
488
func (e *jsonEncDriver) WriteArrayEnd() {
493
e.e.encWr.writen1(']')
496
func (e *jsonEncDriver) WriteMapStart(length int) {
500
e.e.encWr.writen1('{')
503
func (e *jsonEncDriver) WriteMapEnd() {
506
if e.e.c != containerMapStart {
510
e.e.encWr.writen1('}')
513
func (e *jsonEncDriver) quoteStr(s string) {
514
// adapted from std pkg encoding/json
515
const hex = "0123456789abcdef"
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.
523
// We optimize for ascii, by assumining that most characters are in the BMP
524
// and natively consumed by json without much computation.
526
// if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
527
// if (htmlasis && jsonCharSafeSet.isset(b)) || jsonCharHtmlSafeSet.isset(b) {
533
if s[i] < utf8.RuneSelf {
535
w.writestr(s[start:i])
539
w.writen2('\\', s[i])
552
w.writen2(hex[s[i]>>4], hex[s[i]&0xF])
558
c, size := utf8.DecodeRuneInString(s[i:])
559
if c == utf8.RuneError && size == 1 { // meaning invalid encoding (so output as-is)
561
w.writestr(s[start:i])
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') {
572
w.writestr(s[start:i])
575
w.writen1(hex[c&0xF])
582
if start < uint(len(s)) {
583
w.writestr(s[start:])
588
func (e *jsonEncDriver) atEndOfEncode() {
589
if e.h.TermWhitespace {
590
var c byte = ' ' // default is that scalar is written, so output space
592
c = '\n' // for containers (map/list), output a newline
600
type jsonDecState struct {
601
rawext bool // rawext configured on the handle
603
tok uint8 // used to store the token read right after skipWhiteSpace
606
bstr [4]byte // scratch used for string \UXXX parsing
608
// scratch buffer used for base64 decoding (DecodeBytes in reuseBuf mode),
609
// or reading doubleQuoted string (DecodeStringAsBytes, DecodeNaked)
613
func (x jsonDecState) captureState() interface{} { return x }
614
func (x *jsonDecState) restoreState(v interface{}) { *x = v.(jsonDecState) }
616
type jsonDecDriver struct {
618
decDriverNoopNumberHelper
623
// se interfaceExtWrapper
625
// ---- cpu cache line boundary?
630
func (d *jsonDecDriver) descBd() (s string) { panic("descBd unsupported") }
632
func (d *jsonDecDriver) decoder() *Decoder {
636
func (d *jsonDecDriver) ReadMapStart() int {
639
d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
640
return containerLenNil
643
d.d.errorf("read map - expect char '%c' but got char '%c'", '{', d.tok)
646
return containerLenUnknown
649
func (d *jsonDecDriver) ReadArrayStart() int {
652
d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
653
return containerLenNil
656
d.d.errorf("read array - expect char '%c' but got char '%c'", '[', d.tok)
659
return containerLenUnknown
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.
668
func (d *jsonDecDriver) CheckBreak() bool {
670
return d.tok == '}' || d.tok == ']'
673
func (d *jsonDecDriver) ReadArrayElem() {
675
if d.d.c != containerArrayStart {
684
func (d *jsonDecDriver) ReadArrayEnd() {
693
func (d *jsonDecDriver) ReadMapElemKey() {
695
if d.d.c != containerMapStart {
704
func (d *jsonDecDriver) ReadMapElemValue() {
713
func (d *jsonDecDriver) ReadMapEnd() {
722
func (d *jsonDecDriver) readDelimError(xc uint8) {
723
d.d.errorf("read json delimiter - expect char '%c' but got char '%c'", xc, d.tok)
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.
730
func (d *jsonDecDriver) checkLit3(got, expect [3]byte) {
732
if jsonValidateSymbols && got != expect {
733
d.d.errorf("expecting %s: got %s", expect, got)
737
func (d *jsonDecDriver) checkLit4(got, expect [4]byte) {
739
if jsonValidateSymbols && got != expect {
740
d.d.errorf("expecting %s: got %s", expect, got)
744
func (d *jsonDecDriver) skipWhitespace() {
745
d.tok = d.d.decRd.skipWhitespace()
748
func (d *jsonDecDriver) advance() {
754
func (d *jsonDecDriver) nextValueBytes(v []byte) []byte {
755
v, cursor := d.nextValueBytesR(v)
756
decNextValueBytesHelper{d: &d.d}.bytesRdV(&v, cursor)
760
func (d *jsonDecDriver) nextValueBytesR(v0 []byte) (v []byte, cursor uint) {
762
var h = decNextValueBytesHelper{d: &d.d}
765
consumeString := func() {
767
bs := dr.jsonReadAsisChars()
769
if bs[len(bs)-1] != '"' {
770
// last char is '\', so consume next one and try again
771
h.append1(&v, dr.readn1())
776
d.advance() // ignore leading whitespace
777
cursor = d.d.rb.c - 1 // cursor starts just before non-whitespace token
781
h.appendN(&v, dr.jsonReadNum()...)
783
d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
784
h.appendS(&v, jsonLits[jsonLitN:jsonLitN+4])
786
d.checkLit4([4]byte{'a', 'l', 's', 'e'}, d.d.decRd.readn4())
787
h.appendS(&v, jsonLits[jsonLitF:jsonLitF+5])
789
d.checkLit3([3]byte{'r', 'u', 'e'}, d.d.decRd.readn3())
790
h.appendS(&v, jsonLits[jsonLitT:jsonLitT+4])
798
stack = append(stack, elem)
802
for len(stack) != 0 {
809
stack = append(stack, elem)
811
stack = stack[:len(stack)-1]
819
func (d *jsonDecDriver) TryNil() bool {
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)
824
d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
830
func (d *jsonDecDriver) DecodeBool() (v bool) {
833
fquot := d.d.c == containerMapKey && d.tok == '"'
835
d.tok = d.d.decRd.readn1()
839
d.checkLit4([4]byte{'a', 'l', 's', 'e'}, d.d.decRd.readn4())
842
d.checkLit3([3]byte{'r', 'u', 'e'}, d.d.decRd.readn3())
845
d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
848
d.d.errorf("decode bool: got first char %c", d.tok)
857
func (d *jsonDecDriver) DecodeTime() (t time.Time) {
861
d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
864
d.ensureReadingString()
865
bs := d.readUnescapedString()
866
t, err := time.Parse(time.RFC3339, stringView(bs))
871
func (d *jsonDecDriver) ContainerType() (vt valueType) {
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())
887
} else if d.tok == '"' {
888
return valueTypeString
890
return valueTypeUnset
893
func (d *jsonDecDriver) decNumBytes() (bs []byte) {
897
bs = dr.readUntil('"')
898
} else if d.tok == 'n' {
899
d.checkLit3([3]byte{'u', 'l', 'l'}, dr.readn3())
901
if jsonManualInlineDecRdInHotZones {
903
bs = dr.rb.jsonReadNum()
905
bs = dr.ri.jsonReadNum()
908
bs = dr.jsonReadNum()
915
func (d *jsonDecDriver) DecodeUint64() (u uint64) {
917
u, neg, ok := parseInteger_bytes(b)
919
d.d.errorf("negative number cannot be decoded as uint64")
922
d.d.onerror(strconvParseErr(b, "ParseUint"))
927
func (d *jsonDecDriver) DecodeInt64() (v int64) {
929
u, neg, ok := parseInteger_bytes(b)
931
d.d.onerror(strconvParseErr(b, "ParseInt"))
933
if chkOvf.Uint2Int(u, neg) {
934
d.d.errorf("overflow decoding number from %s", b)
944
func (d *jsonDecDriver) DecodeFloat64() (f float64) {
946
bs := d.decNumBytes()
950
f, err = parseFloat64(bs)
955
func (d *jsonDecDriver) DecodeFloat32() (f float32) {
957
bs := d.decNumBytes()
961
f, err = parseFloat32(bs)
966
func (d *jsonDecDriver) DecodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) {
969
d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
975
d.d.decode(&re.Value)
976
} else if ext == SelfExt {
977
d.d.decodeValue(baseRV(rv), d.h.fnNoExt(basetype))
979
d.d.interfaceExtConvertAndDecode(rv, ext)
983
func (d *jsonDecDriver) decBytesFromArray(bs []byte) []byte {
988
bs = append(bs, uint8(d.DecodeUint64()))
989
d.tok = d.d.decRd.skipWhitespace()
992
d.d.errorf("read array element - expect char '%c' but got char '%c'", ',', d.tok)
995
bs = append(bs, uint8(chkOvf.UintV(d.DecodeUint64(), 8)))
996
d.tok = d.d.decRd.skipWhitespace()
1002
func (d *jsonDecDriver) DecodeBytes(bs []byte) (bsOut []byte) {
1003
d.d.decByteState = decByteStateNone
1006
d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
1012
d.d.interfaceExtConvertAndDecode(&bsOut, d.h.RawBytesExt)
1019
d.d.decByteState = decByteStateReuseBuf
1022
return d.decBytesFromArray(bs)
1028
d.ensureReadingString()
1029
bs1 := d.readUnescapedString()
1030
slen := base64.StdEncoding.DecodedLen(len(bs1))
1033
} else if slen <= cap(bs) {
1035
} else if bs == nil {
1036
d.d.decByteState = decByteStateReuseBuf
1037
bsOut = d.d.blist.check(*d.buf, slen)
1038
bsOut = bsOut[:slen]
1041
bsOut = make([]byte, slen)
1043
slen2, err := base64.StdEncoding.Decode(bsOut, bs1)
1045
d.d.errorf("error decoding base64 binary '%s': %v", bs1, err)
1048
bsOut = bsOut[:slen2]
1053
func (d *jsonDecDriver) DecodeStringAsBytes() (s []byte) {
1054
d.d.decByteState = decByteStateNone
1059
return d.dblQuoteStringAsBytes()
1065
d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
1068
d.checkLit4([4]byte{'a', 'l', 's', 'e'}, d.d.decRd.readn4())
1069
return jsonLitb[jsonLitF : jsonLitF+5]
1071
d.checkLit3([3]byte{'r', 'u', 'e'}, d.d.decRd.readn3())
1072
return jsonLitb[jsonLitT : jsonLitT+4]
1076
return d.d.decRd.jsonReadNum()
1080
func (d *jsonDecDriver) ensureReadingString() {
1082
d.d.errorf("expecting string starting with '\"'; got '%c'", d.tok)
1086
func (d *jsonDecDriver) readUnescapedString() (bs []byte) {
1088
bs = d.d.decRd.readUntil('"')
1093
func (d *jsonDecDriver) dblQuoteStringAsBytes() (buf []byte) {
1094
checkUtf8 := d.h.ValidateUnicode
1095
d.d.decByteState = decByteStateNone
1103
var firstTime bool = true
1109
bs = dr.rb.jsonReadAsisChars()
1110
if bs[len(bs)-1] == '"' {
1111
d.d.decByteState = decByteStateZerocopy
1112
return bs[:len(bs)-1]
1118
if jsonManualInlineDecRdInHotZones {
1120
bs = dr.rb.jsonReadAsisChars()
1122
bs = dr.ri.jsonReadAsisChars()
1125
bs = dr.jsonReadAsisChars()
1130
buf = append(buf, bs[:len(bs)-1]...)
1141
case '"', '\\', '/', '\'':
1142
buf = append(buf, c)
1144
buf = append(buf, '\b')
1146
buf = append(buf, '\f')
1148
buf = append(buf, '\n')
1150
buf = append(buf, '\r')
1152
buf = append(buf, '\t')
1154
rr := d.appendStringAsBytesSlashU()
1155
if checkUtf8 && rr == unicode.ReplacementChar {
1156
d.d.errorf("invalid UTF-8 character found after: %s", buf)
1158
buf = append(buf, d.bstr[:utf8.EncodeRune(d.bstr[:], rr)]...)
1161
d.d.errorf("unsupported escaped value: %c", c)
1165
d.d.decByteState = decByteStateReuseBuf
1169
func (d *jsonDecDriver) appendStringAsBytesSlashU() (r rune) {
1172
var cs [4]byte = d.d.decRd.readn4()
1173
if rr = jsonSlashURune(cs); rr == unicode.ReplacementChar {
1174
return unicode.ReplacementChar
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
1184
return utf16.DecodeRune(r, rune(rr))
1186
return unicode.ReplacementChar
1191
func jsonSlashURune(cs [4]byte) (rr uint32) {
1192
for _, c := range cs {
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)
1202
return unicode.ReplacementChar
1208
func (d *jsonDecDriver) nakedNum(z *fauxUnion, bs []byte) (err error) {
1210
if d.h.PreferFloat {
1211
z.v = valueTypeFloat
1212
z.f, err = parseFloat64(bs)
1214
err = parseNumber(bs, z, d.h.SignedInteger)
1219
func (d *jsonDecDriver) DecodeNaked() {
1226
d.checkLit3([3]byte{'u', 'l', 'l'}, d.d.decRd.readn3())
1229
d.checkLit4([4]byte{'a', 'l', 's', 'e'}, d.d.decRd.readn4())
1233
d.checkLit3([3]byte{'r', 'u', 'e'}, d.d.decRd.readn3())
1239
z.v = valueTypeArray
1242
bs = d.dblQuoteStringAsBytes()
1243
if jsonNakedBoolNullInQuotedStr &&
1244
d.h.MapKeyAsString && len(bs) > 0 && d.d.c == containerMapKey {
1256
if err := d.nakedNum(z, bs); err != nil {
1257
z.v = valueTypeString
1258
z.s = d.d.stringZC(bs)
1262
z.v = valueTypeString
1263
z.s = d.d.stringZC(bs)
1266
bs = d.d.decRd.jsonReadNum()
1269
d.d.errorf("decode number from empty string")
1271
if err := d.nakedNum(z, bs); err != nil {
1272
d.d.errorf("decode number from %s: %v", bs, err)
1307
type JsonHandle struct {
1327
IntegerAsString byte
1361
RawBytesExt InterfaceExt
1364
func (h *JsonHandle) isJson() bool { return true }
1367
func (h *JsonHandle) Name() string { return "json" }
1369
func (h *JsonHandle) desc(bd byte) string { return string(bd) }
1371
func (h *JsonHandle) typical() bool {
1372
return h.Indent == 0 && !h.MapKeyAsString && h.IntegerAsString != 'A' && h.IntegerAsString != 'L'
1375
func (h *JsonHandle) newEncDriver() encDriver {
1376
var e = &jsonEncDriver{h: h}
1386
func (h *JsonHandle) newDecDriver() decDriver {
1387
var d = &jsonDecDriver{h: h}
1392
d.d.jsms = h.MapKeyAsString
1398
func (e *jsonEncDriver) resetState() {
1402
func (e *jsonEncDriver) reset() {
1406
e.typical = e.h.typical()
1407
if e.h.HTMLCharsAsIs {
1408
e.s = &jsonCharSafeSet
1410
e.s = &jsonCharHtmlSafeSet
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
1419
func (d *jsonDecDriver) resetState() {
1420
*d.buf = d.d.blist.check(*d.buf, 256)
1424
func (d *jsonDecDriver) reset() {
1426
d.rawext = d.h.RawBytesExt != nil
1429
func jsonFloatStrconvFmtPrec64(f float64) (fmt byte, prec int8) {
1432
fbits := math.Float64bits(f)
1433
abs := math.Float64frombits(fbits &^ (1 << 63))
1434
if abs == 0 || abs == 1 {
1436
} else if abs < 1e-6 || abs >= 1e21 {
1438
} else if noFrac64(fbits) {
1444
func jsonFloatStrconvFmtPrec32(f float32) (fmt byte, prec int8) {
1448
fbits := math.Float32bits(f)
1449
abs := math.Float32frombits(fbits &^ (1 << 31))
1450
if abs == 0 || abs == 1 {
1452
} else if abs < 1e-6 || abs >= 1e21 {
1454
} else if noFrac32(fbits) {
1460
var _ decDriverContainerTracker = (*jsonDecDriver)(nil)
1461
var _ encDriverContainerTracker = (*jsonEncDriver)(nil)
1462
var _ decDriver = (*jsonDecDriver)(nil)
1463
var _ encDriver = (*jsonEncDriver)(nil)