podman

Форк
0
210 строк · 5.2 Кб
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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.