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  }