gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

stream.go (5287B)


      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 }