1
0
mirror of https://github.com/json-iterator/go.git synced 2024-12-09 08:55:35 +02:00
json-iterator/stream.go

211 lines
5.2 KiB
Go
Raw Normal View History

2017-01-07 06:28:16 +02:00
package jsoniter
import (
"io"
)
// stream is a io.Writer like object, with JSON specific write functions.
2017-07-09 08:57:49 +02:00
// Error is not returned as return value, but stored as Error member on this stream instance.
2017-01-07 06:28:16 +02:00
type Stream struct {
cfg *frozenConfig
out io.Writer
buf []byte
Error error
indention int
Attachment interface{} // open for customized encoder
2017-01-07 06:28:16 +02:00
}
2017-07-09 08:57:49 +02:00
// NewStream create new stream instance.
// cfg can be jsoniter.ConfigDefault.
// out can be nil if write to internal buffer.
// bufSize is the initial size for the internal buffer in bytes.
2017-07-09 10:09:23 +02:00
func NewStream(cfg API, out io.Writer, bufSize int) *Stream {
2017-06-13 10:58:53 +02:00
return &Stream{
2017-07-09 10:09:23 +02:00
cfg: cfg.(*frozenConfig),
2017-06-13 11:47:40 +02:00
out: out,
2018-02-14 07:58:51 +02:00
buf: make([]byte, 0, bufSize),
2017-06-13 11:47:40 +02:00
Error: nil,
indention: 0,
2017-06-13 10:58:53 +02:00
}
2017-01-07 06:28:16 +02:00
}
2017-07-09 10:09:23 +02:00
// Pool returns a pool can provide more stream with same configuration
func (stream *Stream) Pool() StreamPool {
return stream.cfg
}
2017-07-09 08:57:49 +02:00
// Reset reuse this stream instance by assign a new writer
func (stream *Stream) Reset(out io.Writer) {
stream.out = out
2018-02-14 07:58:51 +02:00
stream.buf = stream.buf[:0]
2017-02-07 03:24:36 +02:00
}
2017-01-07 06:28:16 +02:00
// Available returns how many bytes are unused in the buffer.
func (stream *Stream) Available() int {
2018-02-14 07:58:51 +02:00
return cap(stream.buf) - len(stream.buf)
2017-01-07 06:28:16 +02:00
}
// Buffered returns the number of bytes that have been written into the current buffer.
func (stream *Stream) Buffered() int {
2018-02-14 07:58:51 +02:00
return len(stream.buf)
2017-01-07 06:28:16 +02:00
}
2017-07-09 08:57:49 +02:00
// Buffer if writer is nil, use this method to take the result
func (stream *Stream) Buffer() []byte {
2018-02-14 07:58:51 +02:00
return stream.buf
2017-06-06 03:44:56 +02:00
}
// SetBuffer allows to append to the internal buffer directly
func (stream *Stream) SetBuffer(buf []byte) {
stream.buf = buf
}
2017-01-07 06:28:16 +02:00
// Write writes the contents of p into the buffer.
// It returns the number of bytes written.
// If nn < len(p), it also returns an error explaining
// why the write is short.
func (stream *Stream) Write(p []byte) (nn int, err error) {
2018-02-14 07:58:51 +02:00
stream.buf = append(stream.buf, p...)
if stream.out != nil {
nn, err = stream.out.Write(stream.buf)
stream.buf = stream.buf[nn:]
return
2017-01-07 06:28:16 +02:00
}
2018-02-14 07:58:51 +02:00
return len(p), nil
2017-01-07 06:28:16 +02:00
}
// WriteByte writes a single byte.
func (stream *Stream) writeByte(c byte) {
2018-02-14 07:58:51 +02:00
stream.buf = append(stream.buf, c)
2017-01-07 06:28:16 +02:00
}
func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) {
2018-02-14 07:58:51 +02:00
stream.buf = append(stream.buf, c1, c2)
2017-01-22 13:28:14 +02:00
}
func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
2018-02-14 07:58:51 +02:00
stream.buf = append(stream.buf, c1, c2, c3)
2017-01-22 13:28:14 +02:00
}
func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
2018-02-14 07:58:51 +02:00
stream.buf = append(stream.buf, c1, c2, c3, c4)
2017-01-22 13:28:14 +02:00
}
func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
2018-02-14 07:58:51 +02:00
stream.buf = append(stream.buf, c1, c2, c3, c4, c5)
2017-01-21 18:04:08 +02:00
}
2017-01-07 06:28:16 +02:00
// Flush writes any buffered data to the underlying io.Writer.
func (stream *Stream) Flush() error {
if stream.out == nil {
2017-06-06 03:44:56 +02:00
return nil
}
if stream.Error != nil {
return stream.Error
2017-01-07 06:28:16 +02:00
}
_, err := stream.out.Write(stream.buf)
2017-01-07 06:28:16 +02:00
if err != nil {
2018-02-14 07:58:51 +02:00
if stream.Error == nil {
stream.Error = err
2017-01-07 06:28:16 +02:00
}
return err
}
stream.buf = stream.buf[:0]
2017-01-07 06:28:16 +02:00
return nil
}
2017-07-09 08:57:49 +02:00
// WriteRaw write string out without quotes, just like []byte
func (stream *Stream) WriteRaw(s string) {
2018-02-14 07:58:51 +02:00
stream.buf = append(stream.buf, s...)
2017-01-07 17:06:48 +02:00
}
2017-07-09 08:57:49 +02:00
// WriteNil write null to stream
2017-01-18 17:33:40 +02:00
func (stream *Stream) WriteNil() {
2017-01-22 13:28:14 +02:00
stream.writeFourBytes('n', 'u', 'l', 'l')
2017-01-07 06:28:16 +02:00
}
2017-07-09 08:57:49 +02:00
// WriteTrue write true to stream
2017-01-07 16:08:45 +02:00
func (stream *Stream) WriteTrue() {
2017-01-22 13:28:14 +02:00
stream.writeFourBytes('t', 'r', 'u', 'e')
2017-01-07 16:08:45 +02:00
}
2017-07-09 08:57:49 +02:00
// WriteFalse write false to stream
2017-01-07 16:08:45 +02:00
func (stream *Stream) WriteFalse() {
2017-01-22 13:28:14 +02:00
stream.writeFiveBytes('f', 'a', 'l', 's', 'e')
2017-01-07 16:08:45 +02:00
}
2017-07-09 08:57:49 +02:00
// WriteBool write true or false into stream
2017-01-07 16:08:45 +02:00
func (stream *Stream) WriteBool(val bool) {
if val {
2017-01-22 13:28:14 +02:00
stream.WriteTrue()
2017-01-07 16:08:45 +02:00
} else {
2017-01-22 13:28:14 +02:00
stream.WriteFalse()
2017-01-07 16:08:45 +02:00
}
}
2017-07-09 08:57:49 +02:00
// WriteObjectStart write { with possible indention
2017-01-07 16:08:45 +02:00
func (stream *Stream) WriteObjectStart() {
stream.indention += stream.cfg.indentionStep
2017-01-07 16:08:45 +02:00
stream.writeByte('{')
stream.writeIndention(0)
}
2017-07-09 08:57:49 +02:00
// WriteObjectField write "field": with possible indention
2017-01-07 16:08:45 +02:00
func (stream *Stream) WriteObjectField(field string) {
stream.WriteString(field)
2017-06-29 14:48:27 +02:00
if stream.indention > 0 {
stream.writeTwoBytes(':', ' ')
} else {
stream.writeByte(':')
}
2017-01-07 16:08:45 +02:00
}
2017-07-09 08:57:49 +02:00
// WriteObjectEnd write } with possible indention
2017-01-07 16:08:45 +02:00
func (stream *Stream) WriteObjectEnd() {
stream.writeIndention(stream.cfg.indentionStep)
stream.indention -= stream.cfg.indentionStep
2017-01-07 16:08:45 +02:00
stream.writeByte('}')
}
// WriteEmptyObject write {}
2017-01-09 13:48:57 +02:00
func (stream *Stream) WriteEmptyObject() {
stream.writeByte('{')
stream.writeByte('}')
}
// WriteMore write , with possible indention
2017-01-07 16:08:45 +02:00
func (stream *Stream) WriteMore() {
stream.writeByte(',')
stream.writeIndention(0)
}
2017-07-09 08:57:49 +02:00
// WriteArrayStart write [ with possible indention
2017-01-07 16:16:20 +02:00
func (stream *Stream) WriteArrayStart() {
stream.indention += stream.cfg.indentionStep
2017-01-07 16:16:20 +02:00
stream.writeByte('[')
stream.writeIndention(0)
}
2017-07-09 08:57:49 +02:00
// WriteEmptyArray write []
2017-01-09 13:48:57 +02:00
func (stream *Stream) WriteEmptyArray() {
stream.writeTwoBytes('[', ']')
2017-01-09 13:48:57 +02:00
}
2017-07-09 08:57:49 +02:00
// WriteArrayEnd write ] with possible indention
2017-01-07 16:16:20 +02:00
func (stream *Stream) WriteArrayEnd() {
stream.writeIndention(stream.cfg.indentionStep)
stream.indention -= stream.cfg.indentionStep
2017-01-07 16:16:20 +02:00
stream.writeByte(']')
}
2017-01-07 16:08:45 +02:00
func (stream *Stream) writeIndention(delta int) {
2017-06-06 03:44:56 +02:00
if stream.indention == 0 {
2017-01-07 16:08:45 +02:00
return
}
stream.writeByte('\n')
toWrite := stream.indention - delta
2018-02-14 07:58:51 +02:00
for i := 0; i < toWrite; i++ {
stream.buf = append(stream.buf, ' ')
2017-01-07 16:08:45 +02:00
}
2017-06-06 03:44:56 +02:00
}