...

Source file src/github.com/json-iterator/go/stream.go

Documentation: github.com/json-iterator/go

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

View as plain text