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