1
2
3
4
5
6
7 package jsontext
8
9 import (
10 "bytes"
11 "io"
12 "math/bits"
13
14 "encoding/json/internal/jsonflags"
15 "encoding/json/internal/jsonopts"
16 "encoding/json/internal/jsonwire"
17 )
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 type Encoder struct {
49 s encoderState
50 }
51
52
53
54 type encoderState struct {
55 state
56 encodeBuffer
57 jsonopts.Struct
58
59 SeenPointers map[any]struct{}
60 }
61
62
63
64
65
66 type encodeBuffer struct {
67 Buf []byte
68
69
70
71 baseOffset int64
72
73 wr io.Writer
74
75
76 maxValue int
77
78 unusedCache []byte
79
80
81 bufStats bufferStatistics
82 }
83
84
85
86
87
88
89
90
91 func NewEncoder(w io.Writer, opts ...Options) *Encoder {
92 e := new(Encoder)
93 e.Reset(w, opts...)
94 return e
95 }
96
97
98
99
100
101 func (e *Encoder) Reset(w io.Writer, opts ...Options) {
102 switch {
103 case e == nil:
104 panic("jsontext: invalid nil Encoder")
105 case w == nil:
106 panic("jsontext: invalid nil io.Writer")
107 case e.s.Flags.Get(jsonflags.WithinArshalCall):
108 panic("jsontext: cannot reset Encoder passed to json.MarshalerTo")
109 }
110 e.s.reset(nil, w, opts...)
111 }
112
113 func (e *encoderState) reset(b []byte, w io.Writer, opts ...Options) {
114 e.state.reset()
115 e.encodeBuffer = encodeBuffer{Buf: b, wr: w, bufStats: e.bufStats}
116 if bb, ok := w.(*bytes.Buffer); ok && bb != nil {
117 e.Buf = bb.Bytes()[bb.Len():]
118 }
119 opts2 := jsonopts.Struct{}
120 opts2.Join(opts...)
121 e.Struct = opts2
122 if e.Flags.Get(jsonflags.Multiline) {
123 if !e.Flags.Has(jsonflags.SpaceAfterColon) {
124 e.Flags.Set(jsonflags.SpaceAfterColon | 1)
125 }
126 if !e.Flags.Has(jsonflags.SpaceAfterComma) {
127 e.Flags.Set(jsonflags.SpaceAfterComma | 0)
128 }
129 if !e.Flags.Has(jsonflags.Indent) {
130 e.Flags.Set(jsonflags.Indent | 1)
131 e.Indent = "\t"
132 }
133 }
134 }
135
136
137
138
139
140
141
142
143
144 func (e *Encoder) Options() Options {
145 return &e.s.Struct
146 }
147
148
149 func (e *encoderState) NeedFlush() bool {
150
151
152
153
154
155
156 return e.wr != nil && (e.Tokens.Depth() == 1 || len(e.Buf) > 3*cap(e.Buf)/4)
157 }
158
159
160
161 func (e *encoderState) Flush() error {
162 if e.wr == nil || e.avoidFlush() {
163 return nil
164 }
165
166
167 if e.Tokens.Depth() == 1 && !e.Flags.Get(jsonflags.OmitTopLevelNewline) {
168 e.Buf = append(e.Buf, '\n')
169 }
170
171
172 e.Names.copyQuotedBuffer(e.Buf)
173
174
175 if bb, ok := e.wr.(*bytes.Buffer); ok {
176
177
178
179
180 n, _ := bb.Write(e.Buf)
181 e.baseOffset += int64(n)
182
183
184
185
186
187
188 if avail := bb.Available(); avail < bb.Len()/4 {
189 bb.Grow(avail + 1)
190 }
191
192 e.Buf = bb.AvailableBuffer()
193 return nil
194 }
195
196
197 n, err := e.wr.Write(e.Buf)
198 e.baseOffset += int64(n)
199 if err != nil {
200
201
202
203 if n > 0 {
204 e.Buf = e.Buf[:copy(e.Buf, e.Buf[n:])]
205 }
206 return &ioError{action: "write", err: err}
207 }
208 e.Buf = e.Buf[:0]
209
210
211
212
213 const maxBufferSize = 4 << 10
214 const growthSizeFactor = 2
215 const growthRateFactor = 2
216
217 grow := cap(e.Buf) <= maxBufferSize/growthSizeFactor
218
219
220 grow = grow && int64(cap(e.Buf)) < e.previousOffsetEnd()/growthRateFactor
221 if grow {
222 e.Buf = make([]byte, 0, cap(e.Buf)*growthSizeFactor)
223 }
224
225 return nil
226 }
227 func (d *encodeBuffer) offsetAt(pos int) int64 { return d.baseOffset + int64(pos) }
228 func (e *encodeBuffer) previousOffsetEnd() int64 { return e.baseOffset + int64(len(e.Buf)) }
229 func (e *encodeBuffer) unflushedBuffer() []byte { return e.Buf }
230
231
232
233 func (e *encoderState) avoidFlush() bool {
234 switch {
235 case e.Tokens.Last.Length() == 0:
236
237
238 return true
239 case e.Tokens.Last.needObjectValue():
240
241
242 return true
243 case e.Tokens.Last.NeedObjectName() && len(e.Buf) >= 2:
244
245 switch string(e.Buf[len(e.Buf)-2:]) {
246 case `ll`, `""`, `{}`, `[]`:
247 return true
248 }
249 }
250 return false
251 }
252
253
254
255 func (e *encoderState) UnwriteEmptyObjectMember(prevName *string) bool {
256 if last := e.Tokens.Last; !last.isObject() || !last.NeedObjectName() || last.Length() == 0 {
257 panic("BUG: must be called on an object after writing a value")
258 }
259
260
261
262 b := e.unflushedBuffer()
263
264
265 var n int
266 if len(b) >= 3 {
267 switch string(b[len(b)-2:]) {
268 case "ll":
269 n = len(`null`)
270 case `""`:
271
272
273 if b[len(b)-3] == '\\' {
274 return false
275 }
276 n = len(`""`)
277 case `{}`:
278 n = len(`{}`)
279 case `[]`:
280 n = len(`[]`)
281 }
282 }
283 if n == 0 {
284 return false
285 }
286
287
288 b = b[:len(b)-n]
289 b = jsonwire.TrimSuffixWhitespace(b)
290 b = jsonwire.TrimSuffixByte(b, ':')
291 b = jsonwire.TrimSuffixString(b)
292 b = jsonwire.TrimSuffixWhitespace(b)
293 b = jsonwire.TrimSuffixByte(b, ',')
294 e.Buf = b
295
296
297 e.Tokens.Last.decrement()
298 e.Tokens.Last.decrement()
299 if !e.Flags.Get(jsonflags.AllowDuplicateNames) {
300 if e.Tokens.Last.isActiveNamespace() {
301 e.Namespaces.Last().removeLast()
302 }
303 }
304 e.Names.clearLast()
305 if prevName != nil {
306 e.Names.copyQuotedBuffer(e.Buf)
307 e.Names.replaceLastUnquotedName(*prevName)
308 }
309 return true
310 }
311
312
313
314 func (e *encoderState) UnwriteOnlyObjectMemberName() string {
315 if last := e.Tokens.Last; !last.isObject() || last.Length() != 1 {
316 panic("BUG: must be called on an object after writing first name")
317 }
318
319
320 b := jsonwire.TrimSuffixString(e.Buf)
321 isVerbatim := bytes.IndexByte(e.Buf[len(b):], '\\') < 0
322 name := string(jsonwire.UnquoteMayCopy(e.Buf[len(b):], isVerbatim))
323 e.Buf = jsonwire.TrimSuffixWhitespace(b)
324
325
326 e.Tokens.Last.decrement()
327 if !e.Flags.Get(jsonflags.AllowDuplicateNames) {
328 if e.Tokens.Last.isActiveNamespace() {
329 e.Namespaces.Last().removeLast()
330 }
331 }
332 e.Names.clearLast()
333 return name
334 }
335
336
337
338
339
340
341
342
343
344
345 func (e *Encoder) WriteToken(t Token) error {
346 return e.s.WriteToken(t)
347 }
348 func (e *encoderState) WriteToken(t Token) error {
349 k := t.Kind()
350 b := e.Buf
351
352
353 b = e.Tokens.MayAppendDelim(b, k)
354 if e.Flags.Get(jsonflags.AnyWhitespace) {
355 b = e.appendWhitespace(b, k)
356 }
357 pos := len(b)
358
359
360 var err error
361 switch k {
362 case 'n':
363 b = append(b, "null"...)
364 err = e.Tokens.appendLiteral()
365 case 'f':
366 b = append(b, "false"...)
367 err = e.Tokens.appendLiteral()
368 case 't':
369 b = append(b, "true"...)
370 err = e.Tokens.appendLiteral()
371 case '"':
372 if b, err = t.appendString(b, &e.Flags); err != nil {
373 break
374 }
375 if e.Tokens.Last.NeedObjectName() {
376 if !e.Flags.Get(jsonflags.AllowDuplicateNames) {
377 if !e.Tokens.Last.isValidNamespace() {
378 err = errInvalidNamespace
379 break
380 }
381 if e.Tokens.Last.isActiveNamespace() && !e.Namespaces.Last().insertQuoted(b[pos:], false) {
382 err = wrapWithObjectName(ErrDuplicateName, b[pos:])
383 break
384 }
385 }
386 e.Names.ReplaceLastQuotedOffset(pos)
387 }
388 err = e.Tokens.appendString()
389 case '0':
390 if b, err = t.appendNumber(b, &e.Flags); err != nil {
391 break
392 }
393 err = e.Tokens.appendNumber()
394 case '{':
395 b = append(b, '{')
396 if err = e.Tokens.pushObject(); err != nil {
397 break
398 }
399 e.Names.push()
400 if !e.Flags.Get(jsonflags.AllowDuplicateNames) {
401 e.Namespaces.push()
402 }
403 case '}':
404 b = append(b, '}')
405 if err = e.Tokens.popObject(); err != nil {
406 break
407 }
408 e.Names.pop()
409 if !e.Flags.Get(jsonflags.AllowDuplicateNames) {
410 e.Namespaces.pop()
411 }
412 case '[':
413 b = append(b, '[')
414 err = e.Tokens.pushArray()
415 case ']':
416 b = append(b, ']')
417 err = e.Tokens.popArray()
418 default:
419 err = errInvalidToken
420 }
421 if err != nil {
422 return wrapSyntacticError(e, err, pos, +1)
423 }
424
425
426 e.Buf = b
427 if e.NeedFlush() {
428 return e.Flush()
429 }
430 return nil
431 }
432
433
434
435
436
437
438
439
440
441
442 func (e *encoderState) AppendRaw(k Kind, safeASCII bool, appendFn func([]byte) ([]byte, error)) error {
443 b := e.Buf
444
445
446 b = e.Tokens.MayAppendDelim(b, k)
447 if e.Flags.Get(jsonflags.AnyWhitespace) {
448 b = e.appendWhitespace(b, k)
449 }
450 pos := len(b)
451
452 var err error
453 switch k {
454 case '"':
455
456
457 b = append(b, '"')
458 if b, err = appendFn(b); err != nil {
459 return err
460 }
461 b = append(b, '"')
462
463
464
465 isVerbatim := safeASCII || !jsonwire.NeedEscape(b[pos+len(`"`):len(b)-len(`"`)])
466 if !isVerbatim {
467 var err error
468 b2 := append(e.unusedCache, b[pos+len(`"`):len(b)-len(`"`)]...)
469 b, err = jsonwire.AppendQuote(b[:pos], string(b2), &e.Flags)
470 e.unusedCache = b2[:0]
471 if err != nil {
472 return wrapSyntacticError(e, err, pos, +1)
473 }
474 }
475
476
477 if e.Tokens.Last.NeedObjectName() {
478 if !e.Flags.Get(jsonflags.AllowDuplicateNames) {
479 if !e.Tokens.Last.isValidNamespace() {
480 return wrapSyntacticError(e, err, pos, +1)
481 }
482 if e.Tokens.Last.isActiveNamespace() && !e.Namespaces.Last().insertQuoted(b[pos:], isVerbatim) {
483 err = wrapWithObjectName(ErrDuplicateName, b[pos:])
484 return wrapSyntacticError(e, err, pos, +1)
485 }
486 }
487 e.Names.ReplaceLastQuotedOffset(pos)
488 }
489 if err := e.Tokens.appendString(); err != nil {
490 return wrapSyntacticError(e, err, pos, +1)
491 }
492 case '0':
493 if b, err = appendFn(b); err != nil {
494 return err
495 }
496 if err := e.Tokens.appendNumber(); err != nil {
497 return wrapSyntacticError(e, err, pos, +1)
498 }
499 default:
500 panic("BUG: invalid kind")
501 }
502
503
504 e.Buf = b
505 if e.NeedFlush() {
506 return e.Flush()
507 }
508 return nil
509 }
510
511
512
513
514
515
516
517
518
519
520
521
522
523 func (e *Encoder) WriteValue(v Value) error {
524 return e.s.WriteValue(v)
525 }
526 func (e *encoderState) WriteValue(v Value) error {
527 e.maxValue |= len(v)
528
529 k := v.Kind()
530 b := e.Buf
531
532
533 b = e.Tokens.MayAppendDelim(b, k)
534 if e.Flags.Get(jsonflags.AnyWhitespace) {
535 b = e.appendWhitespace(b, k)
536 }
537 pos := len(b)
538
539
540 var n int
541 n += jsonwire.ConsumeWhitespace(v[n:])
542 b, m, err := e.reformatValue(b, v[n:], e.Tokens.Depth())
543 if err != nil {
544 return wrapSyntacticError(e, err, pos+n+m, +1)
545 }
546 n += m
547 n += jsonwire.ConsumeWhitespace(v[n:])
548 if len(v) > n {
549 err = jsonwire.NewInvalidCharacterError(v[n:], "after top-level value")
550 return wrapSyntacticError(e, err, pos+n, 0)
551 }
552
553
554 switch k {
555 case 'n', 'f', 't':
556 err = e.Tokens.appendLiteral()
557 case '"':
558 if e.Tokens.Last.NeedObjectName() {
559 if !e.Flags.Get(jsonflags.AllowDuplicateNames) {
560 if !e.Tokens.Last.isValidNamespace() {
561 err = errInvalidNamespace
562 break
563 }
564 if e.Tokens.Last.isActiveNamespace() && !e.Namespaces.Last().insertQuoted(b[pos:], false) {
565 err = wrapWithObjectName(ErrDuplicateName, b[pos:])
566 break
567 }
568 }
569 e.Names.ReplaceLastQuotedOffset(pos)
570 }
571 err = e.Tokens.appendString()
572 case '0':
573 err = e.Tokens.appendNumber()
574 case '{':
575 if err = e.Tokens.pushObject(); err != nil {
576 break
577 }
578 if err = e.Tokens.popObject(); err != nil {
579 panic("BUG: popObject should never fail immediately after pushObject: " + err.Error())
580 }
581 if e.Flags.Get(jsonflags.ReorderRawObjects) {
582 mustReorderObjects(b[pos:])
583 }
584 case '[':
585 if err = e.Tokens.pushArray(); err != nil {
586 break
587 }
588 if err = e.Tokens.popArray(); err != nil {
589 panic("BUG: popArray should never fail immediately after pushArray: " + err.Error())
590 }
591 if e.Flags.Get(jsonflags.ReorderRawObjects) {
592 mustReorderObjects(b[pos:])
593 }
594 }
595 if err != nil {
596 return wrapSyntacticError(e, err, pos, +1)
597 }
598
599
600 e.Buf = b
601 if e.NeedFlush() {
602 return e.Flush()
603 }
604 return nil
605 }
606
607
608
609
610 func (e *encoderState) CountNextDelimWhitespace() (n int) {
611 const next = Kind('"')
612 delim := e.Tokens.needDelim(next)
613 if delim > 0 {
614 n += len(",") | len(":")
615 }
616 if delim == ':' {
617 if e.Flags.Get(jsonflags.SpaceAfterColon) {
618 n += len(" ")
619 }
620 } else {
621 if delim == ',' && e.Flags.Get(jsonflags.SpaceAfterComma) {
622 n += len(" ")
623 }
624 if e.Flags.Get(jsonflags.Multiline) {
625 if m := e.Tokens.NeedIndent(next); m > 0 {
626 n += len("\n") + len(e.IndentPrefix) + (m-1)*len(e.Indent)
627 }
628 }
629 }
630 return n
631 }
632
633
634 func (e *encoderState) appendWhitespace(b []byte, next Kind) []byte {
635 if delim := e.Tokens.needDelim(next); delim == ':' {
636 if e.Flags.Get(jsonflags.SpaceAfterColon) {
637 b = append(b, ' ')
638 }
639 } else {
640 if delim == ',' && e.Flags.Get(jsonflags.SpaceAfterComma) {
641 b = append(b, ' ')
642 }
643 if e.Flags.Get(jsonflags.Multiline) {
644 b = e.AppendIndent(b, e.Tokens.NeedIndent(next))
645 }
646 }
647 return b
648 }
649
650
651
652 func (e *encoderState) AppendIndent(b []byte, n int) []byte {
653 if n == 0 {
654 return b
655 }
656 b = append(b, '\n')
657 b = append(b, e.IndentPrefix...)
658 for ; n > 1; n-- {
659 b = append(b, e.Indent...)
660 }
661 return b
662 }
663
664
665
666
667 func (e *encoderState) reformatValue(dst []byte, src Value, depth int) ([]byte, int, error) {
668
669 if len(src) == 0 {
670 return dst, 0, io.ErrUnexpectedEOF
671 }
672 switch k := Kind(src[0]).normalize(); k {
673 case 'n':
674 if jsonwire.ConsumeNull(src) == 0 {
675 n, err := jsonwire.ConsumeLiteral(src, "null")
676 return dst, n, err
677 }
678 return append(dst, "null"...), len("null"), nil
679 case 'f':
680 if jsonwire.ConsumeFalse(src) == 0 {
681 n, err := jsonwire.ConsumeLiteral(src, "false")
682 return dst, n, err
683 }
684 return append(dst, "false"...), len("false"), nil
685 case 't':
686 if jsonwire.ConsumeTrue(src) == 0 {
687 n, err := jsonwire.ConsumeLiteral(src, "true")
688 return dst, n, err
689 }
690 return append(dst, "true"...), len("true"), nil
691 case '"':
692 if n := jsonwire.ConsumeSimpleString(src); n > 0 {
693 dst = append(dst, src[:n]...)
694 return dst, n, nil
695 }
696 return jsonwire.ReformatString(dst, src, &e.Flags)
697 case '0':
698 if n := jsonwire.ConsumeSimpleNumber(src); n > 0 && !e.Flags.Get(jsonflags.CanonicalizeNumbers) {
699 dst = append(dst, src[:n]...)
700 return dst, n, nil
701 }
702 return jsonwire.ReformatNumber(dst, src, &e.Flags)
703 case '{':
704 return e.reformatObject(dst, src, depth)
705 case '[':
706 return e.reformatArray(dst, src, depth)
707 default:
708 return dst, 0, jsonwire.NewInvalidCharacterError(src, "at start of value")
709 }
710 }
711
712
713
714
715 func (e *encoderState) reformatObject(dst []byte, src Value, depth int) ([]byte, int, error) {
716
717 if len(src) == 0 || src[0] != '{' {
718 panic("BUG: reformatObject must be called with a buffer that starts with '{'")
719 } else if depth == maxNestingDepth+1 {
720 return dst, 0, errMaxDepth
721 }
722 dst = append(dst, '{')
723 n := len("{")
724
725
726 n += jsonwire.ConsumeWhitespace(src[n:])
727 if uint(len(src)) <= uint(n) {
728 return dst, n, io.ErrUnexpectedEOF
729 }
730 if src[n] == '}' {
731 dst = append(dst, '}')
732 n += len("}")
733 return dst, n, nil
734 }
735
736 var err error
737 var names *objectNamespace
738 if !e.Flags.Get(jsonflags.AllowDuplicateNames) {
739 e.Namespaces.push()
740 defer e.Namespaces.pop()
741 names = e.Namespaces.Last()
742 }
743 depth++
744 for {
745
746 if e.Flags.Get(jsonflags.Multiline) {
747 dst = e.AppendIndent(dst, depth)
748 }
749
750
751 n += jsonwire.ConsumeWhitespace(src[n:])
752 if uint(len(src)) <= uint(n) {
753 return dst, n, io.ErrUnexpectedEOF
754 }
755 m := jsonwire.ConsumeSimpleString(src[n:])
756 isVerbatim := m > 0
757 if isVerbatim {
758 dst = append(dst, src[n:n+m]...)
759 } else {
760 dst, m, err = jsonwire.ReformatString(dst, src[n:], &e.Flags)
761 if err != nil {
762 return dst, n + m, err
763 }
764 }
765 quotedName := src[n : n+m]
766 if !e.Flags.Get(jsonflags.AllowDuplicateNames) && !names.insertQuoted(quotedName, isVerbatim) {
767 return dst, n, wrapWithObjectName(ErrDuplicateName, quotedName)
768 }
769 n += m
770
771
772 n += jsonwire.ConsumeWhitespace(src[n:])
773 if uint(len(src)) <= uint(n) {
774 return dst, n, wrapWithObjectName(io.ErrUnexpectedEOF, quotedName)
775 }
776 if src[n] != ':' {
777 err = jsonwire.NewInvalidCharacterError(src[n:], "after object name (expecting ':')")
778 return dst, n, wrapWithObjectName(err, quotedName)
779 }
780 dst = append(dst, ':')
781 n += len(":")
782 if e.Flags.Get(jsonflags.SpaceAfterColon) {
783 dst = append(dst, ' ')
784 }
785
786
787 n += jsonwire.ConsumeWhitespace(src[n:])
788 if uint(len(src)) <= uint(n) {
789 return dst, n, wrapWithObjectName(io.ErrUnexpectedEOF, quotedName)
790 }
791 dst, m, err = e.reformatValue(dst, src[n:], depth)
792 if err != nil {
793 return dst, n + m, wrapWithObjectName(err, quotedName)
794 }
795 n += m
796
797
798 n += jsonwire.ConsumeWhitespace(src[n:])
799 if uint(len(src)) <= uint(n) {
800 return dst, n, io.ErrUnexpectedEOF
801 }
802 switch src[n] {
803 case ',':
804 dst = append(dst, ',')
805 if e.Flags.Get(jsonflags.SpaceAfterComma) {
806 dst = append(dst, ' ')
807 }
808 n += len(",")
809 continue
810 case '}':
811 if e.Flags.Get(jsonflags.Multiline) {
812 dst = e.AppendIndent(dst, depth-1)
813 }
814 dst = append(dst, '}')
815 n += len("}")
816 return dst, n, nil
817 default:
818 return dst, n, jsonwire.NewInvalidCharacterError(src[n:], "after object value (expecting ',' or '}')")
819 }
820 }
821 }
822
823
824
825
826 func (e *encoderState) reformatArray(dst []byte, src Value, depth int) ([]byte, int, error) {
827
828 if len(src) == 0 || src[0] != '[' {
829 panic("BUG: reformatArray must be called with a buffer that starts with '['")
830 } else if depth == maxNestingDepth+1 {
831 return dst, 0, errMaxDepth
832 }
833 dst = append(dst, '[')
834 n := len("[")
835
836
837 n += jsonwire.ConsumeWhitespace(src[n:])
838 if uint(len(src)) <= uint(n) {
839 return dst, n, io.ErrUnexpectedEOF
840 }
841 if src[n] == ']' {
842 dst = append(dst, ']')
843 n += len("]")
844 return dst, n, nil
845 }
846
847 var idx int64
848 var err error
849 depth++
850 for {
851
852 if e.Flags.Get(jsonflags.Multiline) {
853 dst = e.AppendIndent(dst, depth)
854 }
855
856
857 n += jsonwire.ConsumeWhitespace(src[n:])
858 if uint(len(src)) <= uint(n) {
859 return dst, n, io.ErrUnexpectedEOF
860 }
861 var m int
862 dst, m, err = e.reformatValue(dst, src[n:], depth)
863 if err != nil {
864 return dst, n + m, wrapWithArrayIndex(err, idx)
865 }
866 n += m
867
868
869 n += jsonwire.ConsumeWhitespace(src[n:])
870 if uint(len(src)) <= uint(n) {
871 return dst, n, io.ErrUnexpectedEOF
872 }
873 switch src[n] {
874 case ',':
875 dst = append(dst, ',')
876 if e.Flags.Get(jsonflags.SpaceAfterComma) {
877 dst = append(dst, ' ')
878 }
879 n += len(",")
880 idx++
881 continue
882 case ']':
883 if e.Flags.Get(jsonflags.Multiline) {
884 dst = e.AppendIndent(dst, depth-1)
885 }
886 dst = append(dst, ']')
887 n += len("]")
888 return dst, n, nil
889 default:
890 return dst, n, jsonwire.NewInvalidCharacterError(src[n:], "after array value (expecting ',' or ']')")
891 }
892 }
893 }
894
895
896
897
898
899 func (e *Encoder) OutputOffset() int64 {
900 return e.s.previousOffsetEnd()
901 }
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916 func (e *Encoder) UnusedBuffer() []byte {
917
918
919
920
921
922
923 n := 1 << bits.Len(uint(e.s.maxValue|63))
924 if cap(e.s.unusedCache) < n {
925 e.s.unusedCache = make([]byte, 0, n)
926 }
927 return e.s.unusedCache
928 }
929
930
931
932
933
934
935 func (e *Encoder) StackDepth() int {
936
937 return e.s.Tokens.Depth() - 1
938 }
939
940
941
942
943
944
945
946
947
948
949
950
951
952 func (e *Encoder) StackIndex(i int) (Kind, int64) {
953
954 switch s := e.s.Tokens.index(i); {
955 case i > 0 && s.isObject():
956 return '{', s.Length()
957 case i > 0 && s.isArray():
958 return '[', s.Length()
959 default:
960 return 0, s.Length()
961 }
962 }
963
964
965 func (e *Encoder) StackPointer() Pointer {
966 return Pointer(e.s.AppendStackPointer(nil, -1))
967 }
968
969 func (e *encoderState) AppendStackPointer(b []byte, where int) []byte {
970 e.Names.copyQuotedBuffer(e.Buf)
971 return e.state.appendStackPointer(b, where)
972 }
973
View as plain text