stream.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. package encoder
  17. import (
  18. "encoding/json"
  19. "io"
  20. "github.com/bytedance/sonic/internal/encoder/vars"
  21. )
  22. // StreamEncoder uses io.Writer as input.
  23. type StreamEncoder struct {
  24. w io.Writer
  25. Encoder
  26. }
  27. // NewStreamEncoder adapts to encoding/json.NewDecoder API.
  28. //
  29. // NewStreamEncoder returns a new encoder that write to w.
  30. func NewStreamEncoder(w io.Writer) *StreamEncoder {
  31. return &StreamEncoder{w: w}
  32. }
  33. // Encode encodes interface{} as JSON to io.Writer
  34. func (enc *StreamEncoder) Encode(val interface{}) (err error) {
  35. out := vars.NewBytes()
  36. /* encode into the buffer */
  37. err = EncodeInto(out, val, enc.Opts)
  38. if err != nil {
  39. goto free_bytes
  40. }
  41. if enc.indent != "" || enc.prefix != "" {
  42. /* indent the JSON */
  43. buf := vars.NewBuffer()
  44. err = json.Indent(buf, *out, enc.prefix, enc.indent)
  45. if err != nil {
  46. vars.FreeBuffer(buf)
  47. goto free_bytes
  48. }
  49. // according to standard library, terminate each value with a newline...
  50. if enc.Opts & NoEncoderNewline == 0 {
  51. buf.WriteByte('\n')
  52. }
  53. /* copy into io.Writer */
  54. _, err = io.Copy(enc.w, buf)
  55. if err != nil {
  56. vars.FreeBuffer(buf)
  57. goto free_bytes
  58. }
  59. } else {
  60. /* copy into io.Writer */
  61. var n int
  62. buf := *out
  63. for len(buf) > 0 {
  64. n, err = enc.w.Write(buf)
  65. buf = buf[n:]
  66. if err != nil {
  67. goto free_bytes
  68. }
  69. }
  70. // according to standard library, terminate each value with a newline...
  71. if enc.Opts & NoEncoderNewline == 0 {
  72. enc.w.Write([]byte{'\n'})
  73. }
  74. }
  75. free_bytes:
  76. vars.FreeBytes(out)
  77. return err
  78. }