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