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