@@ -14,6 +14,7 @@ import (
14
14
"bytes"
15
15
"encoding"
16
16
"encoding/base64"
17
+ "io"
17
18
"math"
18
19
"reflect"
19
20
"runtime"
@@ -141,7 +142,7 @@ func Marshal(v interface{}) ([]byte, error) {
141
142
if err != nil {
142
143
return nil , err
143
144
}
144
- return e .Bytes (), nil
145
+ return e .buf . Bytes (), nil
145
146
}
146
147
147
148
// MarshalIndent is like Marshal but applies Indent to format the output.
@@ -243,23 +244,68 @@ func (e *MarshalerError) Error() string {
243
244
244
245
var hex = "0123456789abcdef"
245
246
246
- // An encodeState encodes JSON into a bytes.Buffer.
247
+ // An encodeState encodes JSON into a bytes.Buffer,
248
+ // optionally flushing to an io.Writer.
247
249
type encodeState struct {
248
- bytes.Buffer // accumulated output
249
- scratch [64 ]byte
250
+ buf bytes.Buffer // accumulated output
251
+ w io.Writer // optional
252
+ scratch [64 ]byte
250
253
}
251
254
252
255
var encodeStatePool sync.Pool
253
256
254
257
func newEncodeState () * encodeState {
255
258
if v := encodeStatePool .Get (); v != nil {
256
259
e := v .(* encodeState )
257
- e .Reset ()
260
+ e .buf . Reset ()
258
261
return e
259
262
}
260
263
return new (encodeState )
261
264
}
262
265
266
+ const maxBuffer = 256 // bytes
267
+
268
+ func (e * encodeState ) flush (force bool ) error {
269
+ // @ydnar: Non-streaming encoders don’t have a writer.
270
+ if e .w == nil {
271
+ return nil
272
+ }
273
+ if force || e .buf .Len () > maxBuffer {
274
+ b := e .buf .Bytes ()
275
+ n , err := e .w .Write (b )
276
+ e .buf .Reset ()
277
+ if n != len (b ) {
278
+ e .buf .Write (b [n :]) // Keep remaining bytes in the buffer
279
+ }
280
+ return err
281
+ }
282
+ return nil
283
+ }
284
+
285
+ func (e * encodeState ) Write (p []byte ) (int , error ) {
286
+ n , err := e .buf .Write (p )
287
+ if err == nil {
288
+ err = e .flush (false )
289
+ }
290
+ return n , err
291
+ }
292
+
293
+ func (e * encodeState ) WriteString (s string ) (int , error ) {
294
+ n , err := e .buf .WriteString (s )
295
+ if err == nil {
296
+ err = e .flush (false )
297
+ }
298
+ return n , err
299
+ }
300
+
301
+ func (e * encodeState ) WriteByte (c byte ) error {
302
+ err := e .buf .WriteByte (c )
303
+ if err == nil {
304
+ err = e .flush (false )
305
+ }
306
+ return err
307
+ }
308
+
263
309
func (e * encodeState ) marshal (v interface {}) (err error ) {
264
310
defer func () {
265
311
if r := recover (); r != nil {
@@ -423,7 +469,7 @@ func marshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
423
469
b , err := m .MarshalJSON ()
424
470
if err == nil {
425
471
// copy JSON into buffer, checking validity.
426
- err = compact (& e .Buffer , b , true )
472
+ err = compact (& e .buf , b , true )
427
473
}
428
474
if err != nil {
429
475
e .error (& MarshalerError {v .Type (), err })
@@ -440,7 +486,7 @@ func addrMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
440
486
b , err := m .MarshalJSON ()
441
487
if err == nil {
442
488
// copy JSON into buffer, checking validity.
443
- err = compact (& e .Buffer , b , true )
489
+ err = compact (& e .buf , b , true )
444
490
}
445
491
if err != nil {
446
492
e .error (& MarshalerError {v .Type (), err })
@@ -818,7 +864,7 @@ func (sv stringValues) get(i int) string { return sv[i].String() }
818
864
819
865
// NOTE: keep in sync with stringBytes below.
820
866
func (e * encodeState ) string (s string ) (int , error ) {
821
- len0 := e .Len ()
867
+ len0 := e .buf . Len ()
822
868
e .WriteByte ('"' )
823
869
start := 0
824
870
for i := 0 ; i < len (s ); {
@@ -889,12 +935,12 @@ func (e *encodeState) string(s string) (int, error) {
889
935
e .WriteString (s [start :])
890
936
}
891
937
e .WriteByte ('"' )
892
- return e .Len () - len0 , nil
938
+ return e .buf . Len () - len0 , nil
893
939
}
894
940
895
941
// NOTE: keep in sync with string above.
896
942
func (e * encodeState ) stringBytes (s []byte ) (int , error ) {
897
- len0 := e .Len ()
943
+ len0 := e .buf . Len ()
898
944
e .WriteByte ('"' )
899
945
start := 0
900
946
for i := 0 ; i < len (s ); {
@@ -965,7 +1011,7 @@ func (e *encodeState) stringBytes(s []byte) (int, error) {
965
1011
e .Write (s [start :])
966
1012
}
967
1013
e .WriteByte ('"' )
968
- return e .Len () - len0 , nil
1014
+ return e .buf . Len () - len0 , nil
969
1015
}
970
1016
971
1017
// A field represents a single field found in a struct.
0 commit comments