1
2
3
4
5
6
7 package json
8
9 import (
10 "bytes"
11 "errors"
12 "io"
13 )
14
15
16 type Decoder struct {
17 r io.Reader
18 buf []byte
19 d decodeState
20 scanp int
21 scanned int64
22 scan scanner
23 err error
24
25 tokenState int
26 tokenStack []int
27 }
28
29
30
31
32
33 func NewDecoder(r io.Reader) *Decoder {
34 return &Decoder{r: r}
35 }
36
37
38
39 func (dec *Decoder) UseNumber() { dec.d.useNumber = true }
40
41
42
43
44 func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true }
45
46
47
48
49
50
51 func (dec *Decoder) Decode(v any) error {
52 if dec.err != nil {
53 return dec.err
54 }
55
56 if err := dec.tokenPrepareForDecode(); err != nil {
57 return err
58 }
59
60 if !dec.tokenValueAllowed() {
61 return &SyntaxError{msg: "not at beginning of value", Offset: dec.InputOffset()}
62 }
63
64
65 n, err := dec.readValue()
66 if err != nil {
67 return err
68 }
69 dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
70 dec.scanp += n
71
72
73
74
75 err = dec.d.unmarshal(v)
76
77
78 dec.tokenValueEnd()
79
80 return err
81 }
82
83
84
85 func (dec *Decoder) Buffered() io.Reader {
86 return bytes.NewReader(dec.buf[dec.scanp:])
87 }
88
89
90
91 func (dec *Decoder) readValue() (int, error) {
92 dec.scan.reset()
93
94 scanp := dec.scanp
95 var err error
96 Input:
97
98
99 for scanp >= 0 {
100
101
102 for ; scanp < len(dec.buf); scanp++ {
103 c := dec.buf[scanp]
104 dec.scan.bytes++
105 switch dec.scan.step(&dec.scan, c) {
106 case scanEnd:
107
108
109
110 dec.scan.bytes--
111 break Input
112 case scanEndObject, scanEndArray:
113
114
115
116 if stateEndValue(&dec.scan, ' ') == scanEnd {
117 scanp++
118 break Input
119 }
120 case scanError:
121 dec.err = dec.scan.err
122 return 0, dec.scan.err
123 }
124 }
125
126
127
128 if err != nil {
129 if err == io.EOF {
130 if dec.scan.step(&dec.scan, ' ') == scanEnd {
131 break Input
132 }
133 if nonSpace(dec.buf) {
134 err = io.ErrUnexpectedEOF
135 }
136 }
137 dec.err = err
138 return 0, err
139 }
140
141 n := scanp - dec.scanp
142 err = dec.refill()
143 scanp = dec.scanp + n
144 }
145 return scanp - dec.scanp, nil
146 }
147
148 func (dec *Decoder) refill() error {
149
150
151 if dec.scanp > 0 {
152 dec.scanned += int64(dec.scanp)
153 n := copy(dec.buf, dec.buf[dec.scanp:])
154 dec.buf = dec.buf[:n]
155 dec.scanp = 0
156 }
157
158
159 const minRead = 512
160 if cap(dec.buf)-len(dec.buf) < minRead {
161 newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
162 copy(newBuf, dec.buf)
163 dec.buf = newBuf
164 }
165
166
167 n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
168 dec.buf = dec.buf[0 : len(dec.buf)+n]
169
170 return err
171 }
172
173 func nonSpace(b []byte) bool {
174 for _, c := range b {
175 if !isSpace(c) {
176 return true
177 }
178 }
179 return false
180 }
181
182
183 type Encoder struct {
184 w io.Writer
185 err error
186 escapeHTML bool
187
188 indentBuf []byte
189 indentPrefix string
190 indentValue string
191 }
192
193
194 func NewEncoder(w io.Writer) *Encoder {
195 return &Encoder{w: w, escapeHTML: true}
196 }
197
198
199
200
201
202
203
204 func (enc *Encoder) Encode(v any) error {
205 if enc.err != nil {
206 return enc.err
207 }
208
209 e := newEncodeState()
210 defer encodeStatePool.Put(e)
211
212 err := e.marshal(v, encOpts{escapeHTML: enc.escapeHTML})
213 if err != nil {
214 return err
215 }
216
217
218
219
220
221
222
223 e.WriteByte('\n')
224
225 b := e.Bytes()
226 if enc.indentPrefix != "" || enc.indentValue != "" {
227 enc.indentBuf, err = appendIndent(enc.indentBuf[:0], b, enc.indentPrefix, enc.indentValue)
228 if err != nil {
229 return err
230 }
231 b = enc.indentBuf
232 }
233 if _, err = enc.w.Write(b); err != nil {
234 enc.err = err
235 }
236 return err
237 }
238
239
240
241
242 func (enc *Encoder) SetIndent(prefix, indent string) {
243 enc.indentPrefix = prefix
244 enc.indentValue = indent
245 }
246
247
248
249
250
251
252
253
254 func (enc *Encoder) SetEscapeHTML(on bool) {
255 enc.escapeHTML = on
256 }
257
258
259
260
261 type RawMessage []byte
262
263
264 func (m RawMessage) MarshalJSON() ([]byte, error) {
265 if m == nil {
266 return []byte("null"), nil
267 }
268 return m, nil
269 }
270
271
272 func (m *RawMessage) UnmarshalJSON(data []byte) error {
273 if m == nil {
274 return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
275 }
276 *m = append((*m)[0:0], data...)
277 return nil
278 }
279
280 var _ Marshaler = (*RawMessage)(nil)
281 var _ Unmarshaler = (*RawMessage)(nil)
282
283
284
285
286
287
288
289
290
291 type Token any
292
293 const (
294 tokenTopValue = iota
295 tokenArrayStart
296 tokenArrayValue
297 tokenArrayComma
298 tokenObjectStart
299 tokenObjectKey
300 tokenObjectColon
301 tokenObjectValue
302 tokenObjectComma
303 )
304
305
306 func (dec *Decoder) tokenPrepareForDecode() error {
307
308
309
310 switch dec.tokenState {
311 case tokenArrayComma:
312 c, err := dec.peek()
313 if err != nil {
314 return err
315 }
316 if c != ',' {
317 return &SyntaxError{"expected comma after array element", dec.InputOffset()}
318 }
319 dec.scanp++
320 dec.tokenState = tokenArrayValue
321 case tokenObjectColon:
322 c, err := dec.peek()
323 if err != nil {
324 return err
325 }
326 if c != ':' {
327 return &SyntaxError{"expected colon after object key", dec.InputOffset()}
328 }
329 dec.scanp++
330 dec.tokenState = tokenObjectValue
331 }
332 return nil
333 }
334
335 func (dec *Decoder) tokenValueAllowed() bool {
336 switch dec.tokenState {
337 case tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue:
338 return true
339 }
340 return false
341 }
342
343 func (dec *Decoder) tokenValueEnd() {
344 switch dec.tokenState {
345 case tokenArrayStart, tokenArrayValue:
346 dec.tokenState = tokenArrayComma
347 case tokenObjectValue:
348 dec.tokenState = tokenObjectComma
349 }
350 }
351
352
353 type Delim rune
354
355 func (d Delim) String() string {
356 return string(d)
357 }
358
359
360
361
362
363
364
365
366
367
368
369
370 func (dec *Decoder) Token() (Token, error) {
371 for {
372 c, err := dec.peek()
373 if err != nil {
374 return nil, err
375 }
376 switch c {
377 case '[':
378 if !dec.tokenValueAllowed() {
379 return dec.tokenError(c)
380 }
381 dec.scanp++
382 dec.tokenStack = append(dec.tokenStack, dec.tokenState)
383 dec.tokenState = tokenArrayStart
384 return Delim('['), nil
385
386 case ']':
387 if dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma {
388 return dec.tokenError(c)
389 }
390 dec.scanp++
391 dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
392 dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
393 dec.tokenValueEnd()
394 return Delim(']'), nil
395
396 case '{':
397 if !dec.tokenValueAllowed() {
398 return dec.tokenError(c)
399 }
400 dec.scanp++
401 dec.tokenStack = append(dec.tokenStack, dec.tokenState)
402 dec.tokenState = tokenObjectStart
403 return Delim('{'), nil
404
405 case '}':
406 if dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma {
407 return dec.tokenError(c)
408 }
409 dec.scanp++
410 dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
411 dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
412 dec.tokenValueEnd()
413 return Delim('}'), nil
414
415 case ':':
416 if dec.tokenState != tokenObjectColon {
417 return dec.tokenError(c)
418 }
419 dec.scanp++
420 dec.tokenState = tokenObjectValue
421 continue
422
423 case ',':
424 if dec.tokenState == tokenArrayComma {
425 dec.scanp++
426 dec.tokenState = tokenArrayValue
427 continue
428 }
429 if dec.tokenState == tokenObjectComma {
430 dec.scanp++
431 dec.tokenState = tokenObjectKey
432 continue
433 }
434 return dec.tokenError(c)
435
436 case '"':
437 if dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey {
438 var x string
439 old := dec.tokenState
440 dec.tokenState = tokenTopValue
441 err := dec.Decode(&x)
442 dec.tokenState = old
443 if err != nil {
444 return nil, err
445 }
446 dec.tokenState = tokenObjectColon
447 return x, nil
448 }
449 fallthrough
450
451 default:
452 if !dec.tokenValueAllowed() {
453 return dec.tokenError(c)
454 }
455 var x any
456 if err := dec.Decode(&x); err != nil {
457 return nil, err
458 }
459 return x, nil
460 }
461 }
462 }
463
464 func (dec *Decoder) tokenError(c byte) (Token, error) {
465 var context string
466 switch dec.tokenState {
467 case tokenTopValue:
468 context = " looking for beginning of value"
469 case tokenArrayStart, tokenArrayValue, tokenObjectValue:
470 context = " looking for beginning of value"
471 case tokenArrayComma:
472 context = " after array element"
473 case tokenObjectKey:
474 context = " looking for beginning of object key string"
475 case tokenObjectColon:
476 context = " after object key"
477 case tokenObjectComma:
478 context = " after object key:value pair"
479 }
480 return nil, &SyntaxError{"invalid character " + quoteChar(c) + context, dec.InputOffset()}
481 }
482
483
484
485 func (dec *Decoder) More() bool {
486 c, err := dec.peek()
487 return err == nil && c != ']' && c != '}'
488 }
489
490 func (dec *Decoder) peek() (byte, error) {
491 var err error
492 for {
493 for i := dec.scanp; i < len(dec.buf); i++ {
494 c := dec.buf[i]
495 if isSpace(c) {
496 continue
497 }
498 dec.scanp = i
499 return c, nil
500 }
501
502 if err != nil {
503 return 0, err
504 }
505 err = dec.refill()
506 }
507 }
508
509
510
511
512 func (dec *Decoder) InputOffset() int64 {
513 return dec.scanned + int64(dec.scanp)
514 }
515
View as plain text