feature_stream.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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. // Write writes the contents of p into the buffer.
  50. // It returns the number of bytes written.
  51. // If nn < len(p), it also returns an error explaining
  52. // why the write is short.
  53. func (stream *Stream) Write(p []byte) (nn int, err error) {
  54. stream.buf = append(stream.buf, p...)
  55. if stream.out != nil {
  56. nn, err = stream.out.Write(stream.buf)
  57. stream.buf = stream.buf[nn:]
  58. return
  59. }
  60. return len(p), nil
  61. }
  62. // WriteByte writes a single byte.
  63. func (stream *Stream) writeByte(c byte) {
  64. stream.buf = append(stream.buf, c)
  65. }
  66. func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) {
  67. stream.buf = append(stream.buf, c1, c2)
  68. }
  69. func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
  70. stream.buf = append(stream.buf, c1, c2, c3)
  71. }
  72. func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
  73. stream.buf = append(stream.buf, c1, c2, c3, c4)
  74. }
  75. func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
  76. stream.buf = append(stream.buf, c1, c2, c3, c4, c5)
  77. }
  78. // Flush writes any buffered data to the underlying io.Writer.
  79. func (stream *Stream) Flush() error {
  80. if stream.out == nil {
  81. return nil
  82. }
  83. if stream.Error != nil {
  84. return stream.Error
  85. }
  86. n, err := stream.out.Write(stream.buf)
  87. if err != nil {
  88. if stream.Error == nil {
  89. stream.Error = err
  90. }
  91. return err
  92. }
  93. stream.buf = stream.buf[n:]
  94. return nil
  95. }
  96. // WriteRaw write string out without quotes, just like []byte
  97. func (stream *Stream) WriteRaw(s string) {
  98. stream.buf = append(stream.buf, s...)
  99. }
  100. // WriteNil write null to stream
  101. func (stream *Stream) WriteNil() {
  102. stream.writeFourBytes('n', 'u', 'l', 'l')
  103. }
  104. // WriteTrue write true to stream
  105. func (stream *Stream) WriteTrue() {
  106. stream.writeFourBytes('t', 'r', 'u', 'e')
  107. }
  108. // WriteFalse write false to stream
  109. func (stream *Stream) WriteFalse() {
  110. stream.writeFiveBytes('f', 'a', 'l', 's', 'e')
  111. }
  112. // WriteBool write true or false into stream
  113. func (stream *Stream) WriteBool(val bool) {
  114. if val {
  115. stream.WriteTrue()
  116. } else {
  117. stream.WriteFalse()
  118. }
  119. }
  120. // WriteObjectStart write { with possible indention
  121. func (stream *Stream) WriteObjectStart() {
  122. stream.indention += stream.cfg.indentionStep
  123. stream.writeByte('{')
  124. stream.writeIndention(0)
  125. }
  126. // WriteObjectField write "field": with possible indention
  127. func (stream *Stream) WriteObjectField(field string) {
  128. stream.WriteString(field)
  129. if stream.indention > 0 {
  130. stream.writeTwoBytes(':', ' ')
  131. } else {
  132. stream.writeByte(':')
  133. }
  134. }
  135. // WriteObjectEnd write } with possible indention
  136. func (stream *Stream) WriteObjectEnd() {
  137. stream.writeIndention(stream.cfg.indentionStep)
  138. stream.indention -= stream.cfg.indentionStep
  139. stream.writeByte('}')
  140. }
  141. // WriteEmptyObject write {}
  142. func (stream *Stream) WriteEmptyObject() {
  143. stream.writeByte('{')
  144. stream.writeByte('}')
  145. }
  146. // WriteMore write , with possible indention
  147. func (stream *Stream) WriteMore() {
  148. stream.writeByte(',')
  149. stream.writeIndention(0)
  150. stream.Flush()
  151. }
  152. // WriteArrayStart write [ with possible indention
  153. func (stream *Stream) WriteArrayStart() {
  154. stream.indention += stream.cfg.indentionStep
  155. stream.writeByte('[')
  156. stream.writeIndention(0)
  157. }
  158. // WriteEmptyArray write []
  159. func (stream *Stream) WriteEmptyArray() {
  160. stream.writeTwoBytes('[', ']')
  161. }
  162. // WriteArrayEnd write ] with possible indention
  163. func (stream *Stream) WriteArrayEnd() {
  164. stream.writeIndention(stream.cfg.indentionStep)
  165. stream.indention -= stream.cfg.indentionStep
  166. stream.writeByte(']')
  167. }
  168. func (stream *Stream) writeIndention(delta int) {
  169. if stream.indention == 0 {
  170. return
  171. }
  172. stream.writeByte('\n')
  173. toWrite := stream.indention - delta
  174. for i := 0; i < toWrite; i++ {
  175. stream.buf = append(stream.buf, ' ')
  176. }
  177. }