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 }