gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

struct.go (20421B)


      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 			// already exists same key (e.g. Hello and HELLO has same lower case key
    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 	// By allocating one extra capacity than `maxKeyLen`,
    143 	// it is possible to avoid the process of comparing the index of the key with the length of the bitmap each time.
    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 // decode from '\uXXXX'
    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 						// early match
    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 						// early match
    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 						// early match
    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 // skip '\' char
    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 						// early match
    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 // skip '\' char
    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 // decode from '\uXXXX'
    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 }