podman

Форк
0
349 строк · 7.7 Кб
1
package jsoniter
2

3
import (
4
	"encoding/json"
5
	"fmt"
6
	"io"
7
)
8

9
// ValueType the type for JSON element
10
type ValueType int
11

12
const (
13
	// InvalidValue invalid JSON element
14
	InvalidValue ValueType = iota
15
	// StringValue JSON element "string"
16
	StringValue
17
	// NumberValue JSON element 100 or 0.10
18
	NumberValue
19
	// NilValue JSON element null
20
	NilValue
21
	// BoolValue JSON element true or false
22
	BoolValue
23
	// ArrayValue JSON element []
24
	ArrayValue
25
	// ObjectValue JSON element {}
26
	ObjectValue
27
)
28

29
var hexDigits []byte
30
var valueTypes []ValueType
31

32
func init() {
33
	hexDigits = make([]byte, 256)
34
	for i := 0; i < len(hexDigits); i++ {
35
		hexDigits[i] = 255
36
	}
37
	for i := '0'; i <= '9'; i++ {
38
		hexDigits[i] = byte(i - '0')
39
	}
40
	for i := 'a'; i <= 'f'; i++ {
41
		hexDigits[i] = byte((i - 'a') + 10)
42
	}
43
	for i := 'A'; i <= 'F'; i++ {
44
		hexDigits[i] = byte((i - 'A') + 10)
45
	}
46
	valueTypes = make([]ValueType, 256)
47
	for i := 0; i < len(valueTypes); i++ {
48
		valueTypes[i] = InvalidValue
49
	}
50
	valueTypes['"'] = StringValue
51
	valueTypes['-'] = NumberValue
52
	valueTypes['0'] = NumberValue
53
	valueTypes['1'] = NumberValue
54
	valueTypes['2'] = NumberValue
55
	valueTypes['3'] = NumberValue
56
	valueTypes['4'] = NumberValue
57
	valueTypes['5'] = NumberValue
58
	valueTypes['6'] = NumberValue
59
	valueTypes['7'] = NumberValue
60
	valueTypes['8'] = NumberValue
61
	valueTypes['9'] = NumberValue
62
	valueTypes['t'] = BoolValue
63
	valueTypes['f'] = BoolValue
64
	valueTypes['n'] = NilValue
65
	valueTypes['['] = ArrayValue
66
	valueTypes['{'] = ObjectValue
67
}
68

69
// Iterator is a io.Reader like object, with JSON specific read functions.
70
// Error is not returned as return value, but stored as Error member on this iterator instance.
71
type Iterator struct {
72
	cfg              *frozenConfig
73
	reader           io.Reader
74
	buf              []byte
75
	head             int
76
	tail             int
77
	depth            int
78
	captureStartedAt int
79
	captured         []byte
80
	Error            error
81
	Attachment       interface{} // open for customized decoder
82
}
83

84
// NewIterator creates an empty Iterator instance
85
func NewIterator(cfg API) *Iterator {
86
	return &Iterator{
87
		cfg:    cfg.(*frozenConfig),
88
		reader: nil,
89
		buf:    nil,
90
		head:   0,
91
		tail:   0,
92
		depth:  0,
93
	}
94
}
95

96
// Parse creates an Iterator instance from io.Reader
97
func Parse(cfg API, reader io.Reader, bufSize int) *Iterator {
98
	return &Iterator{
99
		cfg:    cfg.(*frozenConfig),
100
		reader: reader,
101
		buf:    make([]byte, bufSize),
102
		head:   0,
103
		tail:   0,
104
		depth:  0,
105
	}
106
}
107

108
// ParseBytes creates an Iterator instance from byte array
109
func ParseBytes(cfg API, input []byte) *Iterator {
110
	return &Iterator{
111
		cfg:    cfg.(*frozenConfig),
112
		reader: nil,
113
		buf:    input,
114
		head:   0,
115
		tail:   len(input),
116
		depth:  0,
117
	}
118
}
119

120
// ParseString creates an Iterator instance from string
121
func ParseString(cfg API, input string) *Iterator {
122
	return ParseBytes(cfg, []byte(input))
123
}
124

125
// Pool returns a pool can provide more iterator with same configuration
126
func (iter *Iterator) Pool() IteratorPool {
127
	return iter.cfg
128
}
129

130
// Reset reuse iterator instance by specifying another reader
131
func (iter *Iterator) Reset(reader io.Reader) *Iterator {
132
	iter.reader = reader
133
	iter.head = 0
134
	iter.tail = 0
135
	iter.depth = 0
136
	return iter
137
}
138

139
// ResetBytes reuse iterator instance by specifying another byte array as input
140
func (iter *Iterator) ResetBytes(input []byte) *Iterator {
141
	iter.reader = nil
142
	iter.buf = input
143
	iter.head = 0
144
	iter.tail = len(input)
145
	iter.depth = 0
146
	return iter
147
}
148

149
// WhatIsNext gets ValueType of relatively next json element
150
func (iter *Iterator) WhatIsNext() ValueType {
151
	valueType := valueTypes[iter.nextToken()]
152
	iter.unreadByte()
153
	return valueType
154
}
155

156
func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool {
157
	for i := iter.head; i < iter.tail; i++ {
158
		c := iter.buf[i]
159
		switch c {
160
		case ' ', '\n', '\t', '\r':
161
			continue
162
		}
163
		iter.head = i
164
		return false
165
	}
166
	return true
167
}
168

169
func (iter *Iterator) isObjectEnd() bool {
170
	c := iter.nextToken()
171
	if c == ',' {
172
		return false
173
	}
174
	if c == '}' {
175
		return true
176
	}
177
	iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c}))
178
	return true
179
}
180

181
func (iter *Iterator) nextToken() byte {
182
	// a variation of skip whitespaces, returning the next non-whitespace token
183
	for {
184
		for i := iter.head; i < iter.tail; i++ {
185
			c := iter.buf[i]
186
			switch c {
187
			case ' ', '\n', '\t', '\r':
188
				continue
189
			}
190
			iter.head = i + 1
191
			return c
192
		}
193
		if !iter.loadMore() {
194
			return 0
195
		}
196
	}
197
}
198

199
// ReportError record a error in iterator instance with current position.
200
func (iter *Iterator) ReportError(operation string, msg string) {
201
	if iter.Error != nil {
202
		if iter.Error != io.EOF {
203
			return
204
		}
205
	}
206
	peekStart := iter.head - 10
207
	if peekStart < 0 {
208
		peekStart = 0
209
	}
210
	peekEnd := iter.head + 10
211
	if peekEnd > iter.tail {
212
		peekEnd = iter.tail
213
	}
214
	parsing := string(iter.buf[peekStart:peekEnd])
215
	contextStart := iter.head - 50
216
	if contextStart < 0 {
217
		contextStart = 0
218
	}
219
	contextEnd := iter.head + 50
220
	if contextEnd > iter.tail {
221
		contextEnd = iter.tail
222
	}
223
	context := string(iter.buf[contextStart:contextEnd])
224
	iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
225
		operation, msg, iter.head-peekStart, parsing, context)
226
}
227

228
// CurrentBuffer gets current buffer as string for debugging purpose
229
func (iter *Iterator) CurrentBuffer() string {
230
	peekStart := iter.head - 10
231
	if peekStart < 0 {
232
		peekStart = 0
233
	}
234
	return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head,
235
		string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
236
}
237

238
func (iter *Iterator) readByte() (ret byte) {
239
	if iter.head == iter.tail {
240
		if iter.loadMore() {
241
			ret = iter.buf[iter.head]
242
			iter.head++
243
			return ret
244
		}
245
		return 0
246
	}
247
	ret = iter.buf[iter.head]
248
	iter.head++
249
	return ret
250
}
251

252
func (iter *Iterator) loadMore() bool {
253
	if iter.reader == nil {
254
		if iter.Error == nil {
255
			iter.head = iter.tail
256
			iter.Error = io.EOF
257
		}
258
		return false
259
	}
260
	if iter.captured != nil {
261
		iter.captured = append(iter.captured,
262
			iter.buf[iter.captureStartedAt:iter.tail]...)
263
		iter.captureStartedAt = 0
264
	}
265
	for {
266
		n, err := iter.reader.Read(iter.buf)
267
		if n == 0 {
268
			if err != nil {
269
				if iter.Error == nil {
270
					iter.Error = err
271
				}
272
				return false
273
			}
274
		} else {
275
			iter.head = 0
276
			iter.tail = n
277
			return true
278
		}
279
	}
280
}
281

282
func (iter *Iterator) unreadByte() {
283
	if iter.Error != nil {
284
		return
285
	}
286
	iter.head--
287
	return
288
}
289

290
// Read read the next JSON element as generic interface{}.
291
func (iter *Iterator) Read() interface{} {
292
	valueType := iter.WhatIsNext()
293
	switch valueType {
294
	case StringValue:
295
		return iter.ReadString()
296
	case NumberValue:
297
		if iter.cfg.configBeforeFrozen.UseNumber {
298
			return json.Number(iter.readNumberAsString())
299
		}
300
		return iter.ReadFloat64()
301
	case NilValue:
302
		iter.skipFourBytes('n', 'u', 'l', 'l')
303
		return nil
304
	case BoolValue:
305
		return iter.ReadBool()
306
	case ArrayValue:
307
		arr := []interface{}{}
308
		iter.ReadArrayCB(func(iter *Iterator) bool {
309
			var elem interface{}
310
			iter.ReadVal(&elem)
311
			arr = append(arr, elem)
312
			return true
313
		})
314
		return arr
315
	case ObjectValue:
316
		obj := map[string]interface{}{}
317
		iter.ReadMapCB(func(Iter *Iterator, field string) bool {
318
			var elem interface{}
319
			iter.ReadVal(&elem)
320
			obj[field] = elem
321
			return true
322
		})
323
		return obj
324
	default:
325
		iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))
326
		return nil
327
	}
328
}
329

330
// limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9
331
const maxDepth = 10000
332

333
func (iter *Iterator) incrementDepth() (success bool) {
334
	iter.depth++
335
	if iter.depth <= maxDepth {
336
		return true
337
	}
338
	iter.ReportError("incrementDepth", "exceeded max depth")
339
	return false
340
}
341

342
func (iter *Iterator) decrementDepth() (success bool) {
343
	iter.depth--
344
	if iter.depth >= 0 {
345
		return true
346
	}
347
	iter.ReportError("decrementDepth", "unexpected negative nesting")
348
	return false
349
}
350

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

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

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

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