forked from mirror/go-json
Fix algorithm of struct field detection
This commit is contained in:
parent
a75b5e9d93
commit
0c1e7c61e0
|
@ -260,6 +260,8 @@ func (d *Decoder) removeConflictFields(fieldMap map[string]*structFieldSet, conf
|
|||
dec: v.dec,
|
||||
offset: baseOffset + v.offset,
|
||||
isTaggedKey: v.isTaggedKey,
|
||||
key: k,
|
||||
keyLen: int64(len(k)),
|
||||
}
|
||||
fieldMap[k] = fieldSet
|
||||
lower := strings.ToLower(k)
|
||||
|
@ -282,6 +284,8 @@ func (d *Decoder) removeConflictFields(fieldMap map[string]*structFieldSet, conf
|
|||
dec: v.dec,
|
||||
offset: baseOffset + v.offset,
|
||||
isTaggedKey: v.isTaggedKey,
|
||||
key: k,
|
||||
keyLen: int64(len(k)),
|
||||
}
|
||||
fieldMap[k] = fieldSet
|
||||
lower := strings.ToLower(k)
|
||||
|
@ -345,6 +349,8 @@ func (d *Decoder) compileStruct(typ *rtype, structName, fieldName string) (decod
|
|||
dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec),
|
||||
offset: field.Offset,
|
||||
isTaggedKey: v.isTaggedKey,
|
||||
key: k,
|
||||
keyLen: int64(len(k)),
|
||||
}
|
||||
fieldMap[k] = fieldSet
|
||||
lower := strings.ToLower(k)
|
||||
|
@ -367,6 +373,8 @@ func (d *Decoder) compileStruct(typ *rtype, structName, fieldName string) (decod
|
|||
dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec),
|
||||
offset: field.Offset,
|
||||
isTaggedKey: v.isTaggedKey,
|
||||
key: k,
|
||||
keyLen: int64(len(k)),
|
||||
}
|
||||
fieldMap[k] = fieldSet
|
||||
lower := strings.ToLower(k)
|
||||
|
@ -388,22 +396,26 @@ func (d *Decoder) compileStruct(typ *rtype, structName, fieldName string) (decod
|
|||
if tag.isString {
|
||||
dec = newWrappedStringDecoder(dec, structName, field.Name)
|
||||
}
|
||||
fieldSet := &structFieldSet{dec: dec, offset: field.Offset, isTaggedKey: tag.isTaggedKey}
|
||||
var key string
|
||||
if tag.key != "" {
|
||||
fieldMap[tag.key] = fieldSet
|
||||
lower := strings.ToLower(tag.key)
|
||||
if _, exists := fieldMap[lower]; !exists {
|
||||
fieldMap[lower] = fieldSet
|
||||
}
|
||||
key = tag.key
|
||||
} else {
|
||||
fieldMap[field.Name] = fieldSet
|
||||
lower := strings.ToLower(field.Name)
|
||||
key = field.Name
|
||||
}
|
||||
fieldSet := &structFieldSet{
|
||||
dec: dec,
|
||||
offset: field.Offset,
|
||||
isTaggedKey: tag.isTaggedKey,
|
||||
key: key,
|
||||
keyLen: int64(len(key)),
|
||||
}
|
||||
fieldMap[key] = fieldSet
|
||||
lower := strings.ToLower(key)
|
||||
if _, exists := fieldMap[lower]; !exists {
|
||||
fieldMap[lower] = fieldSet
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete(d.structTypeToDecoder, typeptr)
|
||||
structDec.tryOptimize()
|
||||
return structDec, nil
|
||||
|
|
|
@ -12,6 +12,8 @@ type structFieldSet struct {
|
|||
dec decoder
|
||||
offset uintptr
|
||||
isTaggedKey bool
|
||||
key string
|
||||
keyLen int64
|
||||
}
|
||||
|
||||
type structDecoder struct {
|
||||
|
@ -157,6 +159,7 @@ func decodeKeyByBitmapInt8(d *structDecoder, buf []byte, cursor int64) (int64, *
|
|||
keyIdx := 0
|
||||
bitmap := d.keyBitmapInt8
|
||||
keyBitmapLen := len(bitmap)
|
||||
start := cursor
|
||||
for {
|
||||
c := char(b, cursor)
|
||||
switch c {
|
||||
|
@ -164,7 +167,12 @@ func decodeKeyByBitmapInt8(d *structDecoder, buf []byte, cursor int64) (int64, *
|
|||
x := uint64(curBit & -curBit)
|
||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
||||
field = d.sortedFieldSets[fieldSetIndex]
|
||||
keyLen := cursor - start
|
||||
cursor++
|
||||
if keyLen < field.keyLen {
|
||||
// early match
|
||||
return cursor, nil, nil
|
||||
}
|
||||
return cursor, field, nil
|
||||
case nul:
|
||||
return 0, nil, errUnexpectedEndOfJSON("string", cursor)
|
||||
|
@ -237,6 +245,7 @@ func decodeKeyByBitmapInt16(d *structDecoder, buf []byte, cursor int64) (int64,
|
|||
keyIdx := 0
|
||||
bitmap := d.keyBitmapInt16
|
||||
keyBitmapLen := len(bitmap)
|
||||
start := cursor
|
||||
for {
|
||||
c := char(b, cursor)
|
||||
switch c {
|
||||
|
@ -244,7 +253,12 @@ func decodeKeyByBitmapInt16(d *structDecoder, buf []byte, cursor int64) (int64,
|
|||
x := uint64(curBit & -curBit)
|
||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
||||
field = d.sortedFieldSets[fieldSetIndex]
|
||||
keyLen := cursor - start
|
||||
cursor++
|
||||
if keyLen < field.keyLen {
|
||||
// early match
|
||||
return cursor, nil, nil
|
||||
}
|
||||
return cursor, field, nil
|
||||
case nul:
|
||||
return 0, nil, errUnexpectedEndOfJSON("string", cursor)
|
||||
|
@ -341,10 +355,13 @@ func decodeKeyByBitmapInt8Stream(d *structDecoder, s *stream) (*structFieldSet,
|
|||
x := uint64(curBit & -curBit)
|
||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
||||
field = d.sortedFieldSets[fieldSetIndex]
|
||||
b := s.buf[start:s.cursor]
|
||||
key := *(*string)(unsafe.Pointer(&b))
|
||||
keyLen := s.cursor - start
|
||||
s.cursor++
|
||||
return field, key, nil
|
||||
if keyLen < field.keyLen {
|
||||
// early match
|
||||
return nil, field.key, nil
|
||||
}
|
||||
return field, field.key, nil
|
||||
case nul:
|
||||
if s.read() {
|
||||
continue
|
||||
|
@ -441,10 +458,13 @@ func decodeKeyByBitmapInt16Stream(d *structDecoder, s *stream) (*structFieldSet,
|
|||
x := uint64(curBit & -curBit)
|
||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
||||
field = d.sortedFieldSets[fieldSetIndex]
|
||||
b := s.buf[start:s.cursor]
|
||||
key := *(*string)(unsafe.Pointer(&b))
|
||||
keyLen := s.cursor - start
|
||||
s.cursor++
|
||||
return field, key, nil
|
||||
if keyLen < field.keyLen {
|
||||
// early match
|
||||
return nil, field.key, nil
|
||||
}
|
||||
return field, field.key, nil
|
||||
case nul:
|
||||
if s.read() {
|
||||
continue
|
||||
|
|
Loading…
Reference in New Issue