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 }