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