podman

Форк
0
405 строк · 9.9 Кб
1
// Package jwriter contains a JSON writer.
2
package jwriter
3

4
import (
5
	"io"
6
	"strconv"
7
	"unicode/utf8"
8

9
	"github.com/mailru/easyjson/buffer"
10
)
11

12
// Flags describe various encoding options. The behavior may be actually implemented in the encoder, but
13
// Flags field in Writer is used to set and pass them around.
14
type Flags int
15

16
const (
17
	NilMapAsEmpty   Flags = 1 << iota // Encode nil map as '{}' rather than 'null'.
18
	NilSliceAsEmpty                   // Encode nil slice as '[]' rather than 'null'.
19
)
20

21
// Writer is a JSON writer.
22
type Writer struct {
23
	Flags Flags
24

25
	Error        error
26
	Buffer       buffer.Buffer
27
	NoEscapeHTML bool
28
}
29

30
// Size returns the size of the data that was written out.
31
func (w *Writer) Size() int {
32
	return w.Buffer.Size()
33
}
34

35
// DumpTo outputs the data to given io.Writer, resetting the buffer.
36
func (w *Writer) DumpTo(out io.Writer) (written int, err error) {
37
	return w.Buffer.DumpTo(out)
38
}
39

40
// BuildBytes returns writer data as a single byte slice. You can optionally provide one byte slice
41
// as argument that it will try to reuse.
42
func (w *Writer) BuildBytes(reuse ...[]byte) ([]byte, error) {
43
	if w.Error != nil {
44
		return nil, w.Error
45
	}
46

47
	return w.Buffer.BuildBytes(reuse...), nil
48
}
49

50
// ReadCloser returns an io.ReadCloser that can be used to read the data.
51
// ReadCloser also resets the buffer.
52
func (w *Writer) ReadCloser() (io.ReadCloser, error) {
53
	if w.Error != nil {
54
		return nil, w.Error
55
	}
56

57
	return w.Buffer.ReadCloser(), nil
58
}
59

60
// RawByte appends raw binary data to the buffer.
61
func (w *Writer) RawByte(c byte) {
62
	w.Buffer.AppendByte(c)
63
}
64

65
// RawByte appends raw binary data to the buffer.
66
func (w *Writer) RawString(s string) {
67
	w.Buffer.AppendString(s)
68
}
69

70
// Raw appends raw binary data to the buffer or sets the error if it is given. Useful for
71
// calling with results of MarshalJSON-like functions.
72
func (w *Writer) Raw(data []byte, err error) {
73
	switch {
74
	case w.Error != nil:
75
		return
76
	case err != nil:
77
		w.Error = err
78
	case len(data) > 0:
79
		w.Buffer.AppendBytes(data)
80
	default:
81
		w.RawString("null")
82
	}
83
}
84

85
// RawText encloses raw binary data in quotes and appends in to the buffer.
86
// Useful for calling with results of MarshalText-like functions.
87
func (w *Writer) RawText(data []byte, err error) {
88
	switch {
89
	case w.Error != nil:
90
		return
91
	case err != nil:
92
		w.Error = err
93
	case len(data) > 0:
94
		w.String(string(data))
95
	default:
96
		w.RawString("null")
97
	}
98
}
99

100
// Base64Bytes appends data to the buffer after base64 encoding it
101
func (w *Writer) Base64Bytes(data []byte) {
102
	if data == nil {
103
		w.Buffer.AppendString("null")
104
		return
105
	}
106
	w.Buffer.AppendByte('"')
107
	w.base64(data)
108
	w.Buffer.AppendByte('"')
109
}
110

111
func (w *Writer) Uint8(n uint8) {
112
	w.Buffer.EnsureSpace(3)
113
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
114
}
115

116
func (w *Writer) Uint16(n uint16) {
117
	w.Buffer.EnsureSpace(5)
118
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
119
}
120

121
func (w *Writer) Uint32(n uint32) {
122
	w.Buffer.EnsureSpace(10)
123
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
124
}
125

126
func (w *Writer) Uint(n uint) {
127
	w.Buffer.EnsureSpace(20)
128
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
129
}
130

131
func (w *Writer) Uint64(n uint64) {
132
	w.Buffer.EnsureSpace(20)
133
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, n, 10)
134
}
135

136
func (w *Writer) Int8(n int8) {
137
	w.Buffer.EnsureSpace(4)
138
	w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
139
}
140

141
func (w *Writer) Int16(n int16) {
142
	w.Buffer.EnsureSpace(6)
143
	w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
144
}
145

146
func (w *Writer) Int32(n int32) {
147
	w.Buffer.EnsureSpace(11)
148
	w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
149
}
150

151
func (w *Writer) Int(n int) {
152
	w.Buffer.EnsureSpace(21)
153
	w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
154
}
155

156
func (w *Writer) Int64(n int64) {
157
	w.Buffer.EnsureSpace(21)
158
	w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, n, 10)
159
}
160

161
func (w *Writer) Uint8Str(n uint8) {
162
	w.Buffer.EnsureSpace(3)
163
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
164
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
165
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
166
}
167

168
func (w *Writer) Uint16Str(n uint16) {
169
	w.Buffer.EnsureSpace(5)
170
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
171
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
172
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
173
}
174

175
func (w *Writer) Uint32Str(n uint32) {
176
	w.Buffer.EnsureSpace(10)
177
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
178
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
179
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
180
}
181

182
func (w *Writer) UintStr(n uint) {
183
	w.Buffer.EnsureSpace(20)
184
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
185
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
186
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
187
}
188

189
func (w *Writer) Uint64Str(n uint64) {
190
	w.Buffer.EnsureSpace(20)
191
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
192
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, n, 10)
193
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
194
}
195

196
func (w *Writer) UintptrStr(n uintptr) {
197
	w.Buffer.EnsureSpace(20)
198
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
199
	w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)
200
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
201
}
202

203
func (w *Writer) Int8Str(n int8) {
204
	w.Buffer.EnsureSpace(4)
205
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
206
	w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
207
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
208
}
209

210
func (w *Writer) Int16Str(n int16) {
211
	w.Buffer.EnsureSpace(6)
212
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
213
	w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
214
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
215
}
216

217
func (w *Writer) Int32Str(n int32) {
218
	w.Buffer.EnsureSpace(11)
219
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
220
	w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
221
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
222
}
223

224
func (w *Writer) IntStr(n int) {
225
	w.Buffer.EnsureSpace(21)
226
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
227
	w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)
228
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
229
}
230

231
func (w *Writer) Int64Str(n int64) {
232
	w.Buffer.EnsureSpace(21)
233
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
234
	w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, n, 10)
235
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
236
}
237

238
func (w *Writer) Float32(n float32) {
239
	w.Buffer.EnsureSpace(20)
240
	w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32)
241
}
242

243
func (w *Writer) Float32Str(n float32) {
244
	w.Buffer.EnsureSpace(20)
245
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
246
	w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32)
247
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
248
}
249

250
func (w *Writer) Float64(n float64) {
251
	w.Buffer.EnsureSpace(20)
252
	w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, n, 'g', -1, 64)
253
}
254

255
func (w *Writer) Float64Str(n float64) {
256
	w.Buffer.EnsureSpace(20)
257
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
258
	w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 64)
259
	w.Buffer.Buf = append(w.Buffer.Buf, '"')
260
}
261

262
func (w *Writer) Bool(v bool) {
263
	w.Buffer.EnsureSpace(5)
264
	if v {
265
		w.Buffer.Buf = append(w.Buffer.Buf, "true"...)
266
	} else {
267
		w.Buffer.Buf = append(w.Buffer.Buf, "false"...)
268
	}
269
}
270

271
const chars = "0123456789abcdef"
272

273
func getTable(falseValues ...int) [128]bool {
274
	table := [128]bool{}
275

276
	for i := 0; i < 128; i++ {
277
		table[i] = true
278
	}
279

280
	for _, v := range falseValues {
281
		table[v] = false
282
	}
283

284
	return table
285
}
286

287
var (
288
	htmlEscapeTable   = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '"', '&', '<', '>', '\\')
289
	htmlNoEscapeTable = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '"', '\\')
290
)
291

292
func (w *Writer) String(s string) {
293
	w.Buffer.AppendByte('"')
294

295
	// Portions of the string that contain no escapes are appended as
296
	// byte slices.
297

298
	p := 0 // last non-escape symbol
299

300
	escapeTable := &htmlEscapeTable
301
	if w.NoEscapeHTML {
302
		escapeTable = &htmlNoEscapeTable
303
	}
304

305
	for i := 0; i < len(s); {
306
		c := s[i]
307

308
		if c < utf8.RuneSelf {
309
			if escapeTable[c] {
310
				// single-width character, no escaping is required
311
				i++
312
				continue
313
			}
314

315
			w.Buffer.AppendString(s[p:i])
316
			switch c {
317
			case '\t':
318
				w.Buffer.AppendString(`\t`)
319
			case '\r':
320
				w.Buffer.AppendString(`\r`)
321
			case '\n':
322
				w.Buffer.AppendString(`\n`)
323
			case '\\':
324
				w.Buffer.AppendString(`\\`)
325
			case '"':
326
				w.Buffer.AppendString(`\"`)
327
			default:
328
				w.Buffer.AppendString(`\u00`)
329
				w.Buffer.AppendByte(chars[c>>4])
330
				w.Buffer.AppendByte(chars[c&0xf])
331
			}
332

333
			i++
334
			p = i
335
			continue
336
		}
337

338
		// broken utf
339
		runeValue, runeWidth := utf8.DecodeRuneInString(s[i:])
340
		if runeValue == utf8.RuneError && runeWidth == 1 {
341
			w.Buffer.AppendString(s[p:i])
342
			w.Buffer.AppendString(`\ufffd`)
343
			i++
344
			p = i
345
			continue
346
		}
347

348
		// jsonp stuff - tab separator and line separator
349
		if runeValue == '\u2028' || runeValue == '\u2029' {
350
			w.Buffer.AppendString(s[p:i])
351
			w.Buffer.AppendString(`\u202`)
352
			w.Buffer.AppendByte(chars[runeValue&0xf])
353
			i += runeWidth
354
			p = i
355
			continue
356
		}
357
		i += runeWidth
358
	}
359
	w.Buffer.AppendString(s[p:])
360
	w.Buffer.AppendByte('"')
361
}
362

363
const encode = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
364
const padChar = '='
365

366
func (w *Writer) base64(in []byte) {
367

368
	if len(in) == 0 {
369
		return
370
	}
371

372
	w.Buffer.EnsureSpace(((len(in)-1)/3 + 1) * 4)
373

374
	si := 0
375
	n := (len(in) / 3) * 3
376

377
	for si < n {
378
		// Convert 3x 8bit source bytes into 4 bytes
379
		val := uint(in[si+0])<<16 | uint(in[si+1])<<8 | uint(in[si+2])
380

381
		w.Buffer.Buf = append(w.Buffer.Buf, encode[val>>18&0x3F], encode[val>>12&0x3F], encode[val>>6&0x3F], encode[val&0x3F])
382

383
		si += 3
384
	}
385

386
	remain := len(in) - si
387
	if remain == 0 {
388
		return
389
	}
390

391
	// Add the remaining small block
392
	val := uint(in[si+0]) << 16
393
	if remain == 2 {
394
		val |= uint(in[si+1]) << 8
395
	}
396

397
	w.Buffer.Buf = append(w.Buffer.Buf, encode[val>>18&0x3F], encode[val>>12&0x3F])
398

399
	switch remain {
400
	case 2:
401
		w.Buffer.Buf = append(w.Buffer.Buf, encode[val>>6&0x3F], byte(padChar))
402
	case 1:
403
		w.Buffer.Buf = append(w.Buffer.Buf, byte(padChar), byte(padChar))
404
	}
405
}
406

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

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

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

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