stream.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package jsoniter
  2. import (
  3. "io"
  4. )
  5. // stream is a io.Writer like object, with JSON specific write functions.
  6. // Error is not returned as return value, but stored as Error member on this stream instance.
  7. type Stream struct {
  8. cfg *frozenConfig
  9. out io.Writer
  10. buf []byte
  11. Error error
  12. indention int
  13. Attachment interface{} // open for customized encoder
  14. }
  15. // NewStream create new stream instance.
  16. // cfg can be jsoniter.ConfigDefault.
  17. // out can be nil if write to internal buffer.
  18. // bufSize is the initial size for the internal buffer in bytes.
  19. func NewStream(cfg API, out io.Writer, bufSize int) *Stream {
  20. return &Stream{
  21. cfg: cfg.(*frozenConfig),
  22. out: out,
  23. buf: make([]byte, 0, bufSize),
  24. Error: nil,
  25. indention: 0,
  26. }
  27. }
  28. // Pool returns a pool can provide more stream with same configuration
  29. func (stream *Stream) Pool() StreamPool {
  30. return stream.cfg
  31. }
  32. // Reset reuse this stream instance by assign a new writer
  33. func (stream *Stream) Reset(out io.Writer) {
  34. stream.out = out
  35. stream.buf = stream.buf[:0]
  36. }
  37. // Available returns how many bytes are unused in the buffer.
  38. func (stream *Stream) Available() int {
  39. return cap(stream.buf) - len(stream.buf)
  40. }
  41. // Buffered returns the number of bytes that have been written into the current buffer.
  42. func (stream *Stream) Buffered() int {
  43. return len(stream.buf)
  44. }
  45. // Buffer if writer is nil, use this method to take the result
  46. func (stream *Stream) Buffer() []byte {
  47. return stream.buf
  48. }
  49. // SetBuffer allows to append to the internal buffer directly
  50. func (stream *Stream) SetBuffer(buf []byte) {
  51. stream.buf = buf
  52. }
  53. // Write writes the contents of p into the buffer.
  54. // It returns the number of bytes written.
  55. // If nn < len(p), it also returns an error explaining
  56. // why the write is short.
  57. func (stream *Stream) Write(p []byte) (nn int, err error) {
  58. stream.buf = append(stream.buf, p...)
  59. if stream.out != nil {
  60. nn, err = stream.out.Write(stream.buf)
  61. stream.buf = stream.buf[nn:]
  62. return
  63. }
  64. return len(p), nil
  65. }
  66. // WriteByte writes a single byte.
  67. func (stream *Stream) writeByte(c byte) {
  68. stream.buf = append(stream.buf, c)
  69. }
  70. func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) {
  71. stream.buf = append(stream.buf, c1, c2)
  72. }
  73. func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
  74. stream.buf = append(stream.buf, c1, c2, c3)
  75. }
  76. func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
  77. stream.buf = append(stream.buf, c1, c2, c3, c4)
  78. }
  79. func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
  80. stream.buf = append(stream.buf, c1, c2, c3, c4, c5)
  81. }
  82. // Flush writes any buffered data to the underlying io.Writer.
  83. func (stream *Stream) Flush() error {
  84. if stream.out == nil {
  85. return nil
  86. }
  87. if stream.Error != nil {
  88. return stream.Error
  89. }
  90. _, err := stream.out.Write(stream.buf)
  91. if err != nil {
  92. if stream.Error == nil {
  93. stream.Error = err
  94. }
  95. return err
  96. }
  97. stream.buf = stream.buf[:0]
  98. return nil
  99. }
  100. // WriteRaw write string out without quotes, just like []byte
  101. func (stream *Stream) WriteRaw(s string) {
  102. stream.buf = append(stream.buf, s...)
  103. }
  104. // WriteNil write null to stream
  105. func (stream *Stream) WriteNil() {
  106. stream.writeFourBytes('n', 'u', 'l', 'l')
  107. }
  108. // WriteTrue write true to stream
  109. func (stream *Stream) WriteTrue() {
  110. stream.writeFourBytes('t', 'r', 'u', 'e')
  111. }
  112. // WriteFalse write false to stream
  113. func (stream *Stream) WriteFalse() {
  114. stream.writeFiveBytes('f', 'a', 'l', 's', 'e')
  115. }
  116. // WriteBool write true or false into stream
  117. func (stream *Stream) WriteBool(val bool) {
  118. if val {
  119. stream.WriteTrue()
  120. } else {
  121. stream.WriteFalse()
  122. }
  123. }
  124. // WriteObjectStart write { with possible indention
  125. func (stream *Stream) WriteObjectStart() {
  126. stream.indention += stream.cfg.indentionStep
  127. stream.writeByte('{')
  128. stream.writeIndention(0)
  129. }
  130. // WriteObjectField write "field": with possible indention
  131. func (stream *Stream) WriteObjectField(field string) {
  132. stream.WriteString(field)
  133. if stream.indention > 0 {
  134. stream.writeTwoBytes(':', ' ')
  135. } else {
  136. stream.writeByte(':')
  137. }
  138. }
  139. // WriteObjectEnd write } with possible indention
  140. func (stream *Stream) WriteObjectEnd() {
  141. stream.writeIndention(stream.cfg.indentionStep)
  142. stream.indention -= stream.cfg.indentionStep
  143. stream.writeByte('}')
  144. }
  145. // WriteEmptyObject write {}
  146. func (stream *Stream) WriteEmptyObject() {
  147. stream.writeByte('{')
  148. stream.writeByte('}')
  149. }
  150. // WriteMore write , with possible indention
  151. func (stream *Stream) WriteMore() {
  152. stream.writeByte(',')
  153. stream.writeIndention(0)
  154. }
  155. // WriteArrayStart write [ with possible indention
  156. func (stream *Stream) WriteArrayStart() {
  157. stream.indention += stream.cfg.indentionStep
  158. stream.writeByte('[')
  159. stream.writeIndention(0)
  160. }
  161. // WriteEmptyArray write []
  162. func (stream *Stream) WriteEmptyArray() {
  163. stream.writeTwoBytes('[', ']')
  164. }
  165. // WriteArrayEnd write ] with possible indention
  166. func (stream *Stream) WriteArrayEnd() {
  167. stream.writeIndention(stream.cfg.indentionStep)
  168. stream.indention -= stream.cfg.indentionStep
  169. stream.writeByte(']')
  170. }
  171. func (stream *Stream) writeIndention(delta int) {
  172. if stream.indention == 0 {
  173. return
  174. }
  175. stream.writeByte('\n')
  176. toWrite := stream.indention - delta
  177. for i := 0; i < toWrite; i++ {
  178. stream.buf = append(stream.buf, ' ')
  179. }
  180. }