1 package decoder
2
3 import (
4 "fmt"
5 "math"
6 "math/bits"
7 "sort"
8 "strings"
9 "unicode"
10 "unicode/utf16"
11 "unsafe"
12
13 "github.com/goccy/go-json/internal/errors"
14 )
15
16 type structFieldSet struct {
17 dec Decoder
18 offset uintptr
19 isTaggedKey bool
20 fieldIdx int
21 key string
22 keyLen int64
23 err error
24 }
25
26 type structDecoder struct {
27 fieldMap map[string]*structFieldSet
28 fieldUniqueNameNum int
29 stringDecoder *stringDecoder
30 structName string
31 fieldName string
32 isTriedOptimize bool
33 keyBitmapUint8 [][256]uint8
34 keyBitmapUint16 [][256]uint16
35 sortedFieldSets []*structFieldSet
36 keyDecoder func(*structDecoder, []byte, int64) (int64, *structFieldSet, error)
37 keyStreamDecoder func(*structDecoder, *Stream) (*structFieldSet, string, error)
38 }
39
40 var (
41 largeToSmallTable [256]byte
42 )
43
44 func init() {
45 for i := 0; i < 256; i++ {
46 c := i
47 if 'A' <= c && c <= 'Z' {
48 c += 'a' - 'A'
49 }
50 largeToSmallTable[i] = byte(c)
51 }
52 }
53
54 func toASCIILower(s string) string {
55 b := []byte(s)
56 for i := range b {
57 b[i] = largeToSmallTable[b[i]]
58 }
59 return string(b)
60 }
61
62 func newStructDecoder(structName, fieldName string, fieldMap map[string]*structFieldSet) *structDecoder {
63 return &structDecoder{
64 fieldMap: fieldMap,
65 stringDecoder: newStringDecoder(structName, fieldName),
66 structName: structName,
67 fieldName: fieldName,
68 keyDecoder: decodeKey,
69 keyStreamDecoder: decodeKeyStream,
70 }
71 }
72
73 const (
74 allowOptimizeMaxKeyLen = 64
75 allowOptimizeMaxFieldLen = 16
76 )
77
78 func (d *structDecoder) tryOptimize() {
79 fieldUniqueNameMap := map[string]int{}
80 fieldIdx := -1
81 for k, v := range d.fieldMap {
82 lower := strings.ToLower(k)
83 idx, exists := fieldUniqueNameMap[lower]
84 if exists {
85 v.fieldIdx = idx
86 } else {
87 fieldIdx++
88 v.fieldIdx = fieldIdx
89 }
90 fieldUniqueNameMap[lower] = fieldIdx
91 }
92 d.fieldUniqueNameNum = len(fieldUniqueNameMap)
93
94 if d.isTriedOptimize {
95 return
96 }
97 fieldMap := map[string]*structFieldSet{}
98 conflicted := map[string]struct{}{}
99 for k, v := range d.fieldMap {
100 key := strings.ToLower(k)
101 if key != k {
102 if key != toASCIILower(k) {
103 d.isTriedOptimize = true
104 return
105 }
106
107 if _, exists := conflicted[key]; exists {
108 d.isTriedOptimize = true
109 return
110 }
111 conflicted[key] = struct{}{}
112 }
113 if field, exists := fieldMap[key]; exists {
114 if field != v {
115 d.isTriedOptimize = true
116 return
117 }
118 }
119 fieldMap[key] = v
120 }
121
122 if len(fieldMap) > allowOptimizeMaxFieldLen {
123 d.isTriedOptimize = true
124 return
125 }
126
127 var maxKeyLen int
128 sortedKeys := []string{}
129 for key := range fieldMap {
130 keyLen := len(key)
131 if keyLen > allowOptimizeMaxKeyLen {
132 d.isTriedOptimize = true
133 return
134 }
135 if maxKeyLen < keyLen {
136 maxKeyLen = keyLen
137 }
138 sortedKeys = append(sortedKeys, key)
139 }
140 sort.Strings(sortedKeys)
141
142
143
144 bitmapLen := maxKeyLen + 1
145 if len(sortedKeys) <= 8 {
146 keyBitmap := make([][256]uint8, bitmapLen)
147 for i, key := range sortedKeys {
148 for j := 0; j < len(key); j++ {
149 c := key[j]
150 keyBitmap[j][c] |= (1 << uint(i))
151 }
152 d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key])
153 }
154 d.keyBitmapUint8 = keyBitmap
155 d.keyDecoder = decodeKeyByBitmapUint8
156 d.keyStreamDecoder = decodeKeyByBitmapUint8Stream
157 } else {
158 keyBitmap := make([][256]uint16, bitmapLen)
159 for i, key := range sortedKeys {
160 for j := 0; j < len(key); j++ {
161 c := key[j]
162 keyBitmap[j][c] |= (1 << uint(i))
163 }
164 d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key])
165 }
166 d.keyBitmapUint16 = keyBitmap
167 d.keyDecoder = decodeKeyByBitmapUint16
168 d.keyStreamDecoder = decodeKeyByBitmapUint16Stream
169 }
170 }
171
172
173 func decodeKeyCharByUnicodeRune(buf []byte, cursor int64) ([]byte, int64, error) {
174 const defaultOffset = 4
175 const surrogateOffset = 6
176
177 if cursor+defaultOffset >= int64(len(buf)) {
178 return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
179 }
180
181 r := unicodeToRune(buf[cursor : cursor+defaultOffset])
182 if utf16.IsSurrogate(r) {
183 cursor += defaultOffset
184 if cursor+surrogateOffset >= int64(len(buf)) || buf[cursor] != '\\' || buf[cursor+1] != 'u' {
185 return []byte(string(unicode.ReplacementChar)), cursor + defaultOffset - 1, nil
186 }
187 cursor += 2
188 r2 := unicodeToRune(buf[cursor : cursor+defaultOffset])
189 if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
190 return []byte(string(r)), cursor + defaultOffset - 1, nil
191 }
192 }
193 return []byte(string(r)), cursor + defaultOffset - 1, nil
194 }
195
196 func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64, error) {
197 c := buf[cursor]
198 cursor++
199 switch c {
200 case '"':
201 return []byte{'"'}, cursor, nil
202 case '\\':
203 return []byte{'\\'}, cursor, nil
204 case '/':
205 return []byte{'/'}, cursor, nil
206 case 'b':
207 return []byte{'\b'}, cursor, nil
208 case 'f':
209 return []byte{'\f'}, cursor, nil
210 case 'n':
211 return []byte{'\n'}, cursor, nil
212 case 'r':
213 return []byte{'\r'}, cursor, nil
214 case 't':
215 return []byte{'\t'}, cursor, nil
216 case 'u':
217 return decodeKeyCharByUnicodeRune(buf, cursor)
218 }
219 return nil, cursor, nil
220 }
221
222 func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
223 var (
224 curBit uint8 = math.MaxUint8
225 )
226 b := (*sliceHeader)(unsafe.Pointer(&buf)).data
227 for {
228 switch char(b, cursor) {
229 case ' ', '\n', '\t', '\r':
230 cursor++
231 case '"':
232 cursor++
233 c := char(b, cursor)
234 switch c {
235 case '"':
236 cursor++
237 return cursor, nil, nil
238 case nul:
239 return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
240 }
241 keyIdx := 0
242 bitmap := d.keyBitmapUint8
243 start := cursor
244 for {
245 c := char(b, cursor)
246 switch c {
247 case '"':
248 fieldSetIndex := bits.TrailingZeros8(curBit)
249 field := d.sortedFieldSets[fieldSetIndex]
250 keyLen := cursor - start
251 cursor++
252 if keyLen < field.keyLen {
253
254 return cursor, nil, nil
255 }
256 return cursor, field, nil
257 case nul:
258 return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
259 case '\\':
260 cursor++
261 chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor)
262 if err != nil {
263 return 0, nil, err
264 }
265 for _, c := range chars {
266 curBit &= bitmap[keyIdx][largeToSmallTable[c]]
267 if curBit == 0 {
268 return decodeKeyNotFound(b, cursor)
269 }
270 keyIdx++
271 }
272 cursor = nextCursor
273 default:
274 curBit &= bitmap[keyIdx][largeToSmallTable[c]]
275 if curBit == 0 {
276 return decodeKeyNotFound(b, cursor)
277 }
278 keyIdx++
279 }
280 cursor++
281 }
282 default:
283 return cursor, nil, errors.ErrInvalidBeginningOfValue(char(b, cursor), cursor)
284 }
285 }
286 }
287
288 func decodeKeyByBitmapUint16(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
289 var (
290 curBit uint16 = math.MaxUint16
291 )
292 b := (*sliceHeader)(unsafe.Pointer(&buf)).data
293 for {
294 switch char(b, cursor) {
295 case ' ', '\n', '\t', '\r':
296 cursor++
297 case '"':
298 cursor++
299 c := char(b, cursor)
300 switch c {
301 case '"':
302 cursor++
303 return cursor, nil, nil
304 case nul:
305 return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
306 }
307 keyIdx := 0
308 bitmap := d.keyBitmapUint16
309 start := cursor
310 for {
311 c := char(b, cursor)
312 switch c {
313 case '"':
314 fieldSetIndex := bits.TrailingZeros16(curBit)
315 field := d.sortedFieldSets[fieldSetIndex]
316 keyLen := cursor - start
317 cursor++
318 if keyLen < field.keyLen {
319
320 return cursor, nil, nil
321 }
322 return cursor, field, nil
323 case nul:
324 return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
325 case '\\':
326 cursor++
327 chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor)
328 if err != nil {
329 return 0, nil, err
330 }
331 for _, c := range chars {
332 curBit &= bitmap[keyIdx][largeToSmallTable[c]]
333 if curBit == 0 {
334 return decodeKeyNotFound(b, cursor)
335 }
336 keyIdx++
337 }
338 cursor = nextCursor
339 default:
340 curBit &= bitmap[keyIdx][largeToSmallTable[c]]
341 if curBit == 0 {
342 return decodeKeyNotFound(b, cursor)
343 }
344 keyIdx++
345 }
346 cursor++
347 }
348 default:
349 return cursor, nil, errors.ErrInvalidBeginningOfValue(char(b, cursor), cursor)
350 }
351 }
352 }
353
354 func decodeKeyNotFound(b unsafe.Pointer, cursor int64) (int64, *structFieldSet, error) {
355 for {
356 cursor++
357 switch char(b, cursor) {
358 case '"':
359 cursor++
360 return cursor, nil, nil
361 case '\\':
362 cursor++
363 if char(b, cursor) == nul {
364 return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
365 }
366 case nul:
367 return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
368 }
369 }
370 }
371
372 func decodeKey(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
373 key, c, err := d.stringDecoder.decodeByte(buf, cursor)
374 if err != nil {
375 return 0, nil, err
376 }
377 cursor = c
378 k := *(*string)(unsafe.Pointer(&key))
379 field, exists := d.fieldMap[k]
380 if !exists {
381 return cursor, nil, nil
382 }
383 return cursor, field, nil
384 }
385
386 func decodeKeyByBitmapUint8Stream(d *structDecoder, s *Stream) (*structFieldSet, string, error) {
387 var (
388 curBit uint8 = math.MaxUint8
389 )
390 _, cursor, p := s.stat()
391 for {
392 switch char(p, cursor) {
393 case ' ', '\n', '\t', '\r':
394 cursor++
395 case nul:
396 s.cursor = cursor
397 if s.read() {
398 _, cursor, p = s.stat()
399 continue
400 }
401 return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset())
402 case '"':
403 cursor++
404 FIRST_CHAR:
405 start := cursor
406 switch char(p, cursor) {
407 case '"':
408 cursor++
409 s.cursor = cursor
410 return nil, "", nil
411 case nul:
412 s.cursor = cursor
413 if s.read() {
414 _, cursor, p = s.stat()
415 goto FIRST_CHAR
416 }
417 return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
418 }
419 keyIdx := 0
420 bitmap := d.keyBitmapUint8
421 for {
422 c := char(p, cursor)
423 switch c {
424 case '"':
425 fieldSetIndex := bits.TrailingZeros8(curBit)
426 field := d.sortedFieldSets[fieldSetIndex]
427 keyLen := cursor - start
428 cursor++
429 s.cursor = cursor
430 if keyLen < field.keyLen {
431
432 return nil, field.key, nil
433 }
434 return field, field.key, nil
435 case nul:
436 s.cursor = cursor
437 if s.read() {
438 _, cursor, p = s.stat()
439 continue
440 }
441 return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
442 case '\\':
443 s.cursor = cursor + 1
444 chars, err := decodeKeyCharByEscapeCharStream(s)
445 if err != nil {
446 return nil, "", err
447 }
448 cursor = s.cursor
449 for _, c := range chars {
450 curBit &= bitmap[keyIdx][largeToSmallTable[c]]
451 if curBit == 0 {
452 s.cursor = cursor
453 return decodeKeyNotFoundStream(s, start)
454 }
455 keyIdx++
456 }
457 default:
458 curBit &= bitmap[keyIdx][largeToSmallTable[c]]
459 if curBit == 0 {
460 s.cursor = cursor
461 return decodeKeyNotFoundStream(s, start)
462 }
463 keyIdx++
464 }
465 cursor++
466 }
467 default:
468 return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset())
469 }
470 }
471 }
472
473 func decodeKeyByBitmapUint16Stream(d *structDecoder, s *Stream) (*structFieldSet, string, error) {
474 var (
475 curBit uint16 = math.MaxUint16
476 )
477 _, cursor, p := s.stat()
478 for {
479 switch char(p, cursor) {
480 case ' ', '\n', '\t', '\r':
481 cursor++
482 case nul:
483 s.cursor = cursor
484 if s.read() {
485 _, cursor, p = s.stat()
486 continue
487 }
488 return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset())
489 case '"':
490 cursor++
491 FIRST_CHAR:
492 start := cursor
493 switch char(p, cursor) {
494 case '"':
495 cursor++
496 s.cursor = cursor
497 return nil, "", nil
498 case nul:
499 s.cursor = cursor
500 if s.read() {
501 _, cursor, p = s.stat()
502 goto FIRST_CHAR
503 }
504 return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
505 }
506 keyIdx := 0
507 bitmap := d.keyBitmapUint16
508 for {
509 c := char(p, cursor)
510 switch c {
511 case '"':
512 fieldSetIndex := bits.TrailingZeros16(curBit)
513 field := d.sortedFieldSets[fieldSetIndex]
514 keyLen := cursor - start
515 cursor++
516 s.cursor = cursor
517 if keyLen < field.keyLen {
518
519 return nil, field.key, nil
520 }
521 return field, field.key, nil
522 case nul:
523 s.cursor = cursor
524 if s.read() {
525 _, cursor, p = s.stat()
526 continue
527 }
528 return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
529 case '\\':
530 s.cursor = cursor + 1
531 chars, err := decodeKeyCharByEscapeCharStream(s)
532 if err != nil {
533 return nil, "", err
534 }
535 cursor = s.cursor
536 for _, c := range chars {
537 curBit &= bitmap[keyIdx][largeToSmallTable[c]]
538 if curBit == 0 {
539 s.cursor = cursor
540 return decodeKeyNotFoundStream(s, start)
541 }
542 keyIdx++
543 }
544 default:
545 curBit &= bitmap[keyIdx][largeToSmallTable[c]]
546 if curBit == 0 {
547 s.cursor = cursor
548 return decodeKeyNotFoundStream(s, start)
549 }
550 keyIdx++
551 }
552 cursor++
553 }
554 default:
555 return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset())
556 }
557 }
558 }
559
560
561 func decodeKeyCharByUnicodeRuneStream(s *Stream) ([]byte, error) {
562 const defaultOffset = 4
563 const surrogateOffset = 6
564
565 if s.cursor+defaultOffset >= s.length {
566 if !s.read() {
567 return nil, errors.ErrInvalidCharacter(s.char(), "escaped unicode char", s.totalOffset())
568 }
569 }
570
571 r := unicodeToRune(s.buf[s.cursor : s.cursor+defaultOffset])
572 if utf16.IsSurrogate(r) {
573 s.cursor += defaultOffset
574 if s.cursor+surrogateOffset >= s.length {
575 s.read()
576 }
577 if s.cursor+surrogateOffset >= s.length || s.buf[s.cursor] != '\\' || s.buf[s.cursor+1] != 'u' {
578 s.cursor += defaultOffset - 1
579 return []byte(string(unicode.ReplacementChar)), nil
580 }
581 r2 := unicodeToRune(s.buf[s.cursor+defaultOffset+2 : s.cursor+surrogateOffset])
582 if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
583 s.cursor += defaultOffset - 1
584 return []byte(string(r)), nil
585 }
586 }
587 s.cursor += defaultOffset - 1
588 return []byte(string(r)), nil
589 }
590
591 func decodeKeyCharByEscapeCharStream(s *Stream) ([]byte, error) {
592 c := s.buf[s.cursor]
593 s.cursor++
594 RETRY:
595 switch c {
596 case '"':
597 return []byte{'"'}, nil
598 case '\\':
599 return []byte{'\\'}, nil
600 case '/':
601 return []byte{'/'}, nil
602 case 'b':
603 return []byte{'\b'}, nil
604 case 'f':
605 return []byte{'\f'}, nil
606 case 'n':
607 return []byte{'\n'}, nil
608 case 'r':
609 return []byte{'\r'}, nil
610 case 't':
611 return []byte{'\t'}, nil
612 case 'u':
613 return decodeKeyCharByUnicodeRuneStream(s)
614 case nul:
615 if !s.read() {
616 return nil, errors.ErrInvalidCharacter(s.char(), "escaped char", s.totalOffset())
617 }
618 goto RETRY
619 default:
620 return nil, errors.ErrUnexpectedEndOfJSON("struct field", s.totalOffset())
621 }
622 }
623
624 func decodeKeyNotFoundStream(s *Stream, start int64) (*structFieldSet, string, error) {
625 buf, cursor, p := s.stat()
626 for {
627 cursor++
628 switch char(p, cursor) {
629 case '"':
630 b := buf[start:cursor]
631 key := *(*string)(unsafe.Pointer(&b))
632 cursor++
633 s.cursor = cursor
634 return nil, key, nil
635 case '\\':
636 cursor++
637 if char(p, cursor) == nul {
638 s.cursor = cursor
639 if !s.read() {
640 return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
641 }
642 buf, cursor, p = s.statForRetry()
643 }
644 case nul:
645 s.cursor = cursor
646 if !s.read() {
647 return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
648 }
649 buf, cursor, p = s.statForRetry()
650 }
651 }
652 }
653
654 func decodeKeyStream(d *structDecoder, s *Stream) (*structFieldSet, string, error) {
655 key, err := d.stringDecoder.decodeStreamByte(s)
656 if err != nil {
657 return nil, "", err
658 }
659 k := *(*string)(unsafe.Pointer(&key))
660 return d.fieldMap[k], k, nil
661 }
662
663 func (d *structDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
664 depth++
665 if depth > maxDecodeNestingDepth {
666 return errors.ErrExceededMaxDepth(s.char(), s.cursor)
667 }
668
669 c := s.skipWhiteSpace()
670 switch c {
671 case 'n':
672 if err := nullBytes(s); err != nil {
673 return err
674 }
675 return nil
676 default:
677 if s.char() != '{' {
678 return errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset())
679 }
680 }
681 s.cursor++
682 if s.skipWhiteSpace() == '}' {
683 s.cursor++
684 return nil
685 }
686 var (
687 seenFields map[int]struct{}
688 seenFieldNum int
689 )
690 firstWin := (s.Option.Flags & FirstWinOption) != 0
691 if firstWin {
692 seenFields = make(map[int]struct{}, d.fieldUniqueNameNum)
693 }
694 for {
695 s.reset()
696 field, key, err := d.keyStreamDecoder(d, s)
697 if err != nil {
698 return err
699 }
700 if s.skipWhiteSpace() != ':' {
701 return errors.ErrExpected("colon after object key", s.totalOffset())
702 }
703 s.cursor++
704 if field != nil {
705 if field.err != nil {
706 return field.err
707 }
708 if firstWin {
709 if _, exists := seenFields[field.fieldIdx]; exists {
710 if err := s.skipValue(depth); err != nil {
711 return err
712 }
713 } else {
714 if err := field.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+field.offset)); err != nil {
715 return err
716 }
717 seenFieldNum++
718 if d.fieldUniqueNameNum <= seenFieldNum {
719 return s.skipObject(depth)
720 }
721 seenFields[field.fieldIdx] = struct{}{}
722 }
723 } else {
724 if err := field.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+field.offset)); err != nil {
725 return err
726 }
727 }
728 } else if s.DisallowUnknownFields {
729 return fmt.Errorf("json: unknown field %q", key)
730 } else {
731 if err := s.skipValue(depth); err != nil {
732 return err
733 }
734 }
735 c := s.skipWhiteSpace()
736 if c == '}' {
737 s.cursor++
738 return nil
739 }
740 if c != ',' {
741 return errors.ErrExpected("comma after object element", s.totalOffset())
742 }
743 s.cursor++
744 }
745 }
746
747 func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
748 buf := ctx.Buf
749 depth++
750 if depth > maxDecodeNestingDepth {
751 return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
752 }
753 buflen := int64(len(buf))
754 cursor = skipWhiteSpace(buf, cursor)
755 b := (*sliceHeader)(unsafe.Pointer(&buf)).data
756 switch char(b, cursor) {
757 case 'n':
758 if err := validateNull(buf, cursor); err != nil {
759 return 0, err
760 }
761 cursor += 4
762 return cursor, nil
763 case '{':
764 default:
765 return 0, errors.ErrInvalidBeginningOfValue(char(b, cursor), cursor)
766 }
767 cursor++
768 cursor = skipWhiteSpace(buf, cursor)
769 if buf[cursor] == '}' {
770 cursor++
771 return cursor, nil
772 }
773 var (
774 seenFields map[int]struct{}
775 seenFieldNum int
776 )
777 firstWin := (ctx.Option.Flags & FirstWinOption) != 0
778 if firstWin {
779 seenFields = make(map[int]struct{}, d.fieldUniqueNameNum)
780 }
781 for {
782 c, field, err := d.keyDecoder(d, buf, cursor)
783 if err != nil {
784 return 0, err
785 }
786 cursor = skipWhiteSpace(buf, c)
787 if char(b, cursor) != ':' {
788 return 0, errors.ErrExpected("colon after object key", cursor)
789 }
790 cursor++
791 if cursor >= buflen {
792 return 0, errors.ErrExpected("object value after colon", cursor)
793 }
794 if field != nil {
795 if field.err != nil {
796 return 0, field.err
797 }
798 if firstWin {
799 if _, exists := seenFields[field.fieldIdx]; exists {
800 c, err := skipValue(buf, cursor, depth)
801 if err != nil {
802 return 0, err
803 }
804 cursor = c
805 } else {
806 c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset))
807 if err != nil {
808 return 0, err
809 }
810 cursor = c
811 seenFieldNum++
812 if d.fieldUniqueNameNum <= seenFieldNum {
813 return skipObject(buf, cursor, depth)
814 }
815 seenFields[field.fieldIdx] = struct{}{}
816 }
817 } else {
818 c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset))
819 if err != nil {
820 return 0, err
821 }
822 cursor = c
823 }
824 } else {
825 c, err := skipValue(buf, cursor, depth)
826 if err != nil {
827 return 0, err
828 }
829 cursor = c
830 }
831 cursor = skipWhiteSpace(buf, cursor)
832 if char(b, cursor) == '}' {
833 cursor++
834 return cursor, nil
835 }
836 if char(b, cursor) != ',' {
837 return 0, errors.ErrExpected("comma after object element", cursor)
838 }
839 cursor++
840 }
841 }
842
843 func (d *structDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
844 return nil, 0, fmt.Errorf("json: struct decoder does not support decode path")
845 }
846
View as plain text