github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/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      buf := newBytes()
    40      out := buf
    41  
    42      /* encode into the buffer */
    43      err = EncodeInto(&out, val, enc.Opts)
    44      if err != nil {
    45          goto free_bytes
    46      }
    47  
    48      if enc.indent != "" || enc.prefix != "" {
    49          /* indent the JSON */
    50          buf := newBuffer()
    51          err = json.Indent(buf, out, enc.prefix, enc.indent)
    52          if err != nil {
    53              freeBuffer(buf)
    54              goto free_bytes
    55          }
    56  
    57          // according to standard library, terminate each value with a newline...
    58          if enc.Opts & NoEncoderNewline == 0 {
    59              buf.WriteByte('\n')
    60          }
    61  
    62          /* copy into io.Writer */
    63          _, err = io.Copy(enc.w, buf)
    64          if err != nil {
    65              freeBuffer(buf)
    66              goto free_bytes
    67          }
    68  
    69      } else {
    70          /* copy into io.Writer */
    71          var n int
    72          for len(out) > 0 {
    73              n, err = enc.w.Write(out)
    74              out = out[n:]
    75              if err != nil {
    76                  goto free_bytes
    77              }
    78          }
    79  
    80          // according to standard library, terminate each value with a newline...
    81          if enc.Opts & NoEncoderNewline == 0 {
    82              enc.w.Write([]byte{'\n'})
    83          }
    84      }
    85  
    86  free_bytes:
    87      freeBytes(buf)
    88      return err
    89  }