github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/internal/encoder/stream.go (about)

     1  /*
     2   * Copyright 2021 ByteDance Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package encoder
    18  
    19  import (
    20  	"encoding/json"
    21  	"io"
    22  )
    23  
    24  // StreamEncoder uses io.Writer as input.
    25  type StreamEncoder struct {
    26  	w io.Writer
    27  	Encoder
    28  }
    29  
    30  // NewStreamEncoder adapts to encoding/json.NewDecoder API.
    31  //
    32  // NewStreamEncoder returns a new encoder that write to w.
    33  func NewStreamEncoder(w io.Writer) *StreamEncoder {
    34  	return &StreamEncoder{w: w}
    35  }
    36  
    37  // Encode encodes interface{} as JSON to io.Writer
    38  func (enc *StreamEncoder) Encode(val interface{}) (err error) {
    39  	out := newBytes()
    40  
    41  	/* encode into the buffer */
    42  	err = EncodeInto(&out, val, enc.Opts)
    43  	if err != nil {
    44  		goto free_bytes
    45  	}
    46  
    47  	if enc.indent != "" || enc.prefix != "" {
    48  		/* indent the JSON */
    49  		buf := newBuffer()
    50  		err = json.Indent(buf, out, enc.prefix, enc.indent)
    51  		if err != nil {
    52  			freeBuffer(buf)
    53  			goto free_bytes
    54  		}
    55  
    56  		// according to standard library, terminate each value with a newline...
    57  		buf.WriteByte('\n')
    58  
    59  		/* copy into io.Writer */
    60  		_, err = io.Copy(enc.w, buf)
    61  		if err != nil {
    62  			freeBuffer(buf)
    63  			goto free_bytes
    64  		}
    65  
    66  	} else {
    67  		/* copy into io.Writer */
    68  		var n int
    69  		for len(out) > 0 {
    70  			n, err = enc.w.Write(out)
    71  			out = out[n:]
    72  			if err != nil {
    73  				goto free_bytes
    74  			}
    75  		}
    76  
    77  		// according to standard library, terminate each value with a newline...
    78  		enc.w.Write([]byte{'\n'})
    79  	}
    80  
    81  free_bytes:
    82  	freeBytes(out)
    83  	return err
    84  }