1
0
mirror of https://github.com/json-iterator/go.git synced 2024-12-09 08:55:35 +02:00
json-iterator/feature_reflect_object.go

1112 lines
30 KiB
Go
Raw Normal View History

2017-01-07 01:49:50 +02:00
package jsoniter
import (
"fmt"
2017-06-06 17:27:00 +02:00
"io"
2017-01-07 01:49:50 +02:00
"reflect"
2017-06-06 17:27:00 +02:00
"unsafe"
2017-01-07 01:49:50 +02:00
)
func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
type bindingTo struct {
binding *Binding
toName string
ignored bool
}
orderedBindings := []*bindingTo{}
structDescriptor, err := describeStruct(cfg, typ)
if err != nil {
return nil, err
}
for _, binding := range structDescriptor.Fields {
2017-06-20 07:33:40 +02:00
for _, toName := range binding.ToNames {
new := &bindingTo{
binding: binding,
toName: toName,
2017-06-23 02:21:02 +02:00
}
for _, old := range orderedBindings {
if old.toName != toName {
continue
}
old.ignored, new.ignored = resolveConflictBinding(old.binding, new.binding)
}
orderedBindings = append(orderedBindings, new)
2017-06-06 17:27:00 +02:00
}
2017-01-09 13:19:48 +02:00
}
if len(orderedBindings) == 0 {
2017-01-09 13:19:48 +02:00
return &emptyStructEncoder{}, nil
}
2017-06-23 02:21:02 +02:00
finalOrderedFields := []structFieldTo{}
for _, bindingTo := range orderedBindings {
if !bindingTo.ignored {
finalOrderedFields = append(finalOrderedFields, structFieldTo{
encoder: bindingTo.binding.Encoder.(*structFieldEncoder),
toName: bindingTo.toName,
})
}
}
return &structEncoder{structDescriptor.onePtrEmbedded, structDescriptor.onePtrOptimization, finalOrderedFields}, nil
}
func resolveConflictBinding(old, new *Binding) (ignoreOld, ignoreNew bool) {
newTagged := new.Field.Tag.Get("json") != ""
oldTagged := old.Field.Tag.Get("json") != ""
if newTagged {
if oldTagged {
if len(old.levels) > len(new.levels) {
return true, false
} else if len(new.levels) > len(old.levels) {
return false, true
} else {
return true, true
}
} else {
return true, false
}
} else {
if oldTagged {
return true, false
} else {
if len(old.levels) > len(new.levels) {
return true, false
} else if len(new.levels) > len(old.levels) {
return false, true
} else {
return true, true
}
2017-06-23 02:21:02 +02:00
}
}
2017-01-09 13:19:48 +02:00
}
func decoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
bindings := map[string]*Binding{}
structDescriptor, err := describeStruct(cfg, typ)
if err != nil {
return nil, err
2017-01-07 01:49:50 +02:00
}
for _, binding := range structDescriptor.Fields {
2017-06-20 07:33:40 +02:00
for _, fromName := range binding.FromNames {
old := bindings[fromName]
if old == nil {
bindings[fromName] = binding
continue
}
ignoreOld, ignoreNew := resolveConflictBinding(old, binding)
if ignoreOld {
delete(bindings, fromName)
}
if !ignoreNew {
bindings[fromName] = binding
}
2017-05-24 03:39:11 +02:00
}
}
fields := map[string]*structFieldDecoder{}
for k, binding := range bindings {
fields[k] = binding.Decoder.(*structFieldDecoder)
}
return createStructDecoder(typ, fields)
2017-05-24 03:39:11 +02:00
}
func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (ValDecoder, error) {
2017-02-08 07:46:28 +02:00
knownHash := map[int32]struct{}{
2017-06-06 17:27:00 +02:00
0: {},
2017-02-08 07:46:28 +02:00
}
2017-01-07 01:49:50 +02:00
switch len(fields) {
case 0:
return &skipDecoder{typ}, nil
case 1:
for fieldName, fieldDecoder := range fields {
2017-02-08 07:46:28 +02:00
fieldHash := calcHash(fieldName)
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
} else {
knownHash[fieldHash] = struct{}{}
}
return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}, nil
2017-01-07 01:49:50 +02:00
}
case 2:
2017-02-08 07:46:28 +02:00
var fieldHash1 int32
var fieldHash2 int32
2017-01-07 01:49:50 +02:00
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
2017-02-08 07:46:28 +02:00
fieldHash := calcHash(fieldName)
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
} else {
knownHash[fieldHash] = struct{}{}
}
if fieldHash1 == 0 {
fieldHash1 = fieldHash
2017-01-07 01:49:50 +02:00
fieldDecoder1 = fieldDecoder
} else {
2017-02-08 07:46:28 +02:00
fieldHash2 = fieldHash
2017-01-07 01:49:50 +02:00
fieldDecoder2 = fieldDecoder
}
}
2017-02-08 07:46:28 +02:00
return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}, nil
2017-01-07 01:49:50 +02:00
case 3:
2017-02-08 07:46:28 +02:00
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
2017-01-07 01:49:50 +02:00
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
2017-02-08 07:46:28 +02:00
fieldHash := calcHash(fieldName)
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
} else {
knownHash[fieldHash] = struct{}{}
}
if fieldName1 == 0 {
fieldName1 = fieldHash
2017-01-07 01:49:50 +02:00
fieldDecoder1 = fieldDecoder
2017-02-08 07:46:28 +02:00
} else if fieldName2 == 0 {
fieldName2 = fieldHash
2017-01-07 01:49:50 +02:00
fieldDecoder2 = fieldDecoder
} else {
2017-02-08 07:46:28 +02:00
fieldName3 = fieldHash
2017-01-07 01:49:50 +02:00
fieldDecoder3 = fieldDecoder
}
}
return &threeFieldsStructDecoder{typ,
2017-06-29 14:40:25 +02:00
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil
2017-01-07 01:49:50 +02:00
case 4:
2017-02-08 07:46:28 +02:00
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
2017-01-07 01:49:50 +02:00
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
2017-02-08 07:46:28 +02:00
fieldHash := calcHash(fieldName)
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
} else {
knownHash[fieldHash] = struct{}{}
}
if fieldName1 == 0 {
fieldName1 = fieldHash
2017-01-07 01:49:50 +02:00
fieldDecoder1 = fieldDecoder
2017-02-08 07:46:28 +02:00
} else if fieldName2 == 0 {
fieldName2 = fieldHash
2017-01-07 01:49:50 +02:00
fieldDecoder2 = fieldDecoder
2017-02-08 07:46:28 +02:00
} else if fieldName3 == 0 {
fieldName3 = fieldHash
2017-01-07 01:49:50 +02:00
fieldDecoder3 = fieldDecoder
} else {
2017-02-08 07:46:28 +02:00
fieldName4 = fieldHash
2017-01-07 01:49:50 +02:00
fieldDecoder4 = fieldDecoder
}
}
return &fourFieldsStructDecoder{typ,
2017-06-29 14:40:25 +02:00
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4}, nil
2017-02-08 07:46:28 +02:00
case 5:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
var fieldDecoder5 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
} else {
knownHash[fieldHash] = struct{}{}
}
if fieldName1 == 0 {
fieldName1 = fieldHash
fieldDecoder1 = fieldDecoder
} else if fieldName2 == 0 {
fieldName2 = fieldHash
fieldDecoder2 = fieldDecoder
} else if fieldName3 == 0 {
fieldName3 = fieldHash
fieldDecoder3 = fieldDecoder
} else if fieldName4 == 0 {
fieldName4 = fieldHash
fieldDecoder4 = fieldDecoder
} else {
fieldName5 = fieldHash
fieldDecoder5 = fieldDecoder
}
}
return &fiveFieldsStructDecoder{typ,
2017-06-29 14:40:25 +02:00
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil
2017-02-08 07:46:28 +02:00
case 6:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName6 int32
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
var fieldDecoder5 *structFieldDecoder
var fieldDecoder6 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
} else {
knownHash[fieldHash] = struct{}{}
}
if fieldName1 == 0 {
fieldName1 = fieldHash
fieldDecoder1 = fieldDecoder
} else if fieldName2 == 0 {
fieldName2 = fieldHash
fieldDecoder2 = fieldDecoder
} else if fieldName3 == 0 {
fieldName3 = fieldHash
fieldDecoder3 = fieldDecoder
} else if fieldName4 == 0 {
fieldName4 = fieldHash
fieldDecoder4 = fieldDecoder
} else if fieldName5 == 0 {
fieldName5 = fieldHash
fieldDecoder5 = fieldDecoder
} else {
fieldName6 = fieldHash
fieldDecoder6 = fieldDecoder
}
}
return &sixFieldsStructDecoder{typ,
2017-06-29 14:40:25 +02:00
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil
2017-02-08 07:46:28 +02:00
case 7:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName6 int32
var fieldName7 int32
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
var fieldDecoder5 *structFieldDecoder
var fieldDecoder6 *structFieldDecoder
var fieldDecoder7 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
} else {
knownHash[fieldHash] = struct{}{}
}
if fieldName1 == 0 {
fieldName1 = fieldHash
fieldDecoder1 = fieldDecoder
} else if fieldName2 == 0 {
fieldName2 = fieldHash
fieldDecoder2 = fieldDecoder
} else if fieldName3 == 0 {
fieldName3 = fieldHash
fieldDecoder3 = fieldDecoder
} else if fieldName4 == 0 {
fieldName4 = fieldHash
fieldDecoder4 = fieldDecoder
} else if fieldName5 == 0 {
fieldName5 = fieldHash
fieldDecoder5 = fieldDecoder
} else if fieldName6 == 0 {
fieldName6 = fieldHash
fieldDecoder6 = fieldDecoder
} else {
fieldName7 = fieldHash
fieldDecoder7 = fieldDecoder
}
}
return &sevenFieldsStructDecoder{typ,
2017-06-29 14:40:25 +02:00
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7}, nil
2017-02-08 07:46:28 +02:00
case 8:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName6 int32
var fieldName7 int32
var fieldName8 int32
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
var fieldDecoder5 *structFieldDecoder
var fieldDecoder6 *structFieldDecoder
var fieldDecoder7 *structFieldDecoder
var fieldDecoder8 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
} else {
knownHash[fieldHash] = struct{}{}
}
if fieldName1 == 0 {
fieldName1 = fieldHash
fieldDecoder1 = fieldDecoder
} else if fieldName2 == 0 {
fieldName2 = fieldHash
fieldDecoder2 = fieldDecoder
} else if fieldName3 == 0 {
fieldName3 = fieldHash
fieldDecoder3 = fieldDecoder
} else if fieldName4 == 0 {
fieldName4 = fieldHash
fieldDecoder4 = fieldDecoder
} else if fieldName5 == 0 {
fieldName5 = fieldHash
fieldDecoder5 = fieldDecoder
} else if fieldName6 == 0 {
fieldName6 = fieldHash
fieldDecoder6 = fieldDecoder
} else if fieldName7 == 0 {
fieldName7 = fieldHash
fieldDecoder7 = fieldDecoder
} else {
fieldName8 = fieldHash
fieldDecoder8 = fieldDecoder
}
}
return &eightFieldsStructDecoder{typ,
2017-06-29 14:40:25 +02:00
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil
2017-02-08 07:46:28 +02:00
case 9:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName6 int32
var fieldName7 int32
var fieldName8 int32
var fieldName9 int32
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
var fieldDecoder5 *structFieldDecoder
var fieldDecoder6 *structFieldDecoder
var fieldDecoder7 *structFieldDecoder
var fieldDecoder8 *structFieldDecoder
var fieldDecoder9 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
} else {
knownHash[fieldHash] = struct{}{}
}
if fieldName1 == 0 {
fieldName1 = fieldHash
fieldDecoder1 = fieldDecoder
} else if fieldName2 == 0 {
fieldName2 = fieldHash
fieldDecoder2 = fieldDecoder
} else if fieldName3 == 0 {
fieldName3 = fieldHash
fieldDecoder3 = fieldDecoder
} else if fieldName4 == 0 {
fieldName4 = fieldHash
fieldDecoder4 = fieldDecoder
} else if fieldName5 == 0 {
fieldName5 = fieldHash
fieldDecoder5 = fieldDecoder
} else if fieldName6 == 0 {
fieldName6 = fieldHash
fieldDecoder6 = fieldDecoder
} else if fieldName7 == 0 {
fieldName7 = fieldHash
fieldDecoder7 = fieldDecoder
} else if fieldName8 == 0 {
fieldName8 = fieldHash
fieldDecoder8 = fieldDecoder
} else {
fieldName9 = fieldHash
fieldDecoder9 = fieldDecoder
}
}
return &nineFieldsStructDecoder{typ,
2017-06-29 14:40:25 +02:00
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil
2017-02-08 07:46:28 +02:00
case 10:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName6 int32
var fieldName7 int32
var fieldName8 int32
var fieldName9 int32
var fieldName10 int32
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
var fieldDecoder5 *structFieldDecoder
var fieldDecoder6 *structFieldDecoder
var fieldDecoder7 *structFieldDecoder
var fieldDecoder8 *structFieldDecoder
var fieldDecoder9 *structFieldDecoder
var fieldDecoder10 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
} else {
knownHash[fieldHash] = struct{}{}
}
if fieldName1 == 0 {
fieldName1 = fieldHash
fieldDecoder1 = fieldDecoder
} else if fieldName2 == 0 {
fieldName2 = fieldHash
fieldDecoder2 = fieldDecoder
} else if fieldName3 == 0 {
fieldName3 = fieldHash
fieldDecoder3 = fieldDecoder
} else if fieldName4 == 0 {
fieldName4 = fieldHash
fieldDecoder4 = fieldDecoder
} else if fieldName5 == 0 {
fieldName5 = fieldHash
fieldDecoder5 = fieldDecoder
} else if fieldName6 == 0 {
fieldName6 = fieldHash
fieldDecoder6 = fieldDecoder
} else if fieldName7 == 0 {
fieldName7 = fieldHash
fieldDecoder7 = fieldDecoder
} else if fieldName8 == 0 {
fieldName8 = fieldHash
fieldDecoder8 = fieldDecoder
} else if fieldName9 == 0 {
fieldName9 = fieldHash
fieldDecoder9 = fieldDecoder
} else {
fieldName10 = fieldHash
fieldDecoder10 = fieldDecoder
}
}
return &tenFieldsStructDecoder{typ,
2017-06-29 14:40:25 +02:00
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9,
fieldName10, fieldDecoder10}, nil
2017-01-07 01:49:50 +02:00
}
return &generalStructDecoder{typ, fields}, nil
}
type generalStructDecoder struct {
typ reflect.Type
fields map[string]*structFieldDecoder
}
2017-06-20 09:11:01 +02:00
func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-01-07 01:49:50 +02:00
if !iter.readObjectStart() {
return
}
2017-01-20 06:40:52 +02:00
fieldBytes := iter.readObjectFieldAsBytes()
field := *(*string)(unsafe.Pointer(&fieldBytes))
2017-01-07 01:49:50 +02:00
fieldDecoder := decoder.fields[field]
if fieldDecoder == nil {
iter.Skip()
} else {
2017-06-20 09:11:01 +02:00
fieldDecoder.Decode(ptr, iter)
2017-01-07 01:49:50 +02:00
}
for iter.nextToken() == ',' {
2017-01-20 06:40:52 +02:00
fieldBytes = iter.readObjectFieldAsBytes()
field = *(*string)(unsafe.Pointer(&fieldBytes))
2017-01-07 01:49:50 +02:00
fieldDecoder = decoder.fields[field]
if fieldDecoder == nil {
iter.Skip()
} else {
2017-06-20 09:11:01 +02:00
fieldDecoder.Decode(ptr, iter)
2017-01-07 01:49:50 +02:00
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type skipDecoder struct {
typ reflect.Type
}
2017-06-20 09:11:01 +02:00
func (decoder *skipDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-01-07 01:49:50 +02:00
iter.Skip()
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type oneFieldStructDecoder struct {
typ reflect.Type
2017-02-08 07:46:28 +02:00
fieldHash int32
2017-01-07 01:49:50 +02:00
fieldDecoder *structFieldDecoder
}
2017-06-20 09:11:01 +02:00
func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-01-07 01:49:50 +02:00
if !iter.readObjectStart() {
return
}
2017-02-08 07:46:28 +02:00
for {
if iter.readFieldHash() == decoder.fieldHash {
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder.Decode(ptr, iter)
2017-01-07 01:49:50 +02:00
} else {
iter.Skip()
}
2017-07-06 10:04:52 +02:00
if iter.isObjectEnd() {
2017-02-08 07:46:28 +02:00
break
}
2017-01-07 01:49:50 +02:00
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type twoFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldDecoder2 *structFieldDecoder
2017-01-07 01:49:50 +02:00
}
2017-06-20 09:11:01 +02:00
func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-01-07 01:49:50 +02:00
if !iter.readObjectStart() {
return
}
2017-02-08 07:46:28 +02:00
for {
switch iter.readFieldHash() {
case decoder.fieldHash1:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder1.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash2:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder2.Decode(ptr, iter)
2017-01-07 01:49:50 +02:00
default:
iter.Skip()
}
2017-07-06 10:04:52 +02:00
if iter.isObjectEnd() {
2017-02-08 07:46:28 +02:00
break
}
2017-01-07 01:49:50 +02:00
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type threeFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldDecoder3 *structFieldDecoder
2017-01-07 01:49:50 +02:00
}
2017-06-20 09:11:01 +02:00
func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-01-07 01:49:50 +02:00
if !iter.readObjectStart() {
return
}
2017-02-08 07:46:28 +02:00
for {
switch iter.readFieldHash() {
case decoder.fieldHash1:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder1.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash2:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder2.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash3:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder3.Decode(ptr, iter)
2017-01-07 01:49:50 +02:00
default:
iter.Skip()
}
2017-07-06 10:04:52 +02:00
if iter.isObjectEnd() {
2017-02-08 07:46:28 +02:00
break
}
2017-01-07 01:49:50 +02:00
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type fourFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldDecoder4 *structFieldDecoder
2017-01-07 01:49:50 +02:00
}
2017-06-20 09:11:01 +02:00
func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-01-07 01:49:50 +02:00
if !iter.readObjectStart() {
return
}
2017-02-08 07:46:28 +02:00
for {
switch iter.readFieldHash() {
case decoder.fieldHash1:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder1.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash2:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder2.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash3:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder3.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash4:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder4.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
default:
iter.Skip()
}
2017-07-06 10:04:52 +02:00
if iter.isObjectEnd() {
2017-02-08 07:46:28 +02:00
break
}
2017-01-07 01:49:50 +02:00
}
2017-02-08 07:46:28 +02:00
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type fiveFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldDecoder5 *structFieldDecoder
2017-02-08 07:46:28 +02:00
}
2017-06-20 09:11:01 +02:00
func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-02-08 07:46:28 +02:00
if !iter.readObjectStart() {
return
}
for {
switch iter.readFieldHash() {
case decoder.fieldHash1:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder1.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash2:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder2.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash3:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder3.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash4:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder4.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash5:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder5.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
default:
iter.Skip()
}
2017-07-06 10:04:52 +02:00
if iter.isObjectEnd() {
2017-02-08 07:46:28 +02:00
break
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type sixFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldDecoder5 *structFieldDecoder
fieldHash6 int32
fieldDecoder6 *structFieldDecoder
2017-02-08 07:46:28 +02:00
}
2017-06-20 09:11:01 +02:00
func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-02-08 07:46:28 +02:00
if !iter.readObjectStart() {
return
}
for {
switch iter.readFieldHash() {
case decoder.fieldHash1:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder1.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash2:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder2.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash3:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder3.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash4:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder4.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash5:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder5.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash6:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder6.Decode(ptr, iter)
2017-01-07 01:49:50 +02:00
default:
iter.Skip()
}
2017-07-06 10:04:52 +02:00
if iter.isObjectEnd() {
2017-02-08 07:46:28 +02:00
break
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type sevenFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldDecoder5 *structFieldDecoder
fieldHash6 int32
fieldDecoder6 *structFieldDecoder
fieldHash7 int32
fieldDecoder7 *structFieldDecoder
2017-02-08 07:46:28 +02:00
}
2017-06-20 09:11:01 +02:00
func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-02-08 07:46:28 +02:00
if !iter.readObjectStart() {
return
}
for {
switch iter.readFieldHash() {
case decoder.fieldHash1:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder1.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash2:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder2.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash3:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder3.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash4:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder4.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash5:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder5.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash6:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder6.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash7:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder7.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
default:
iter.Skip()
}
2017-07-06 10:04:52 +02:00
if iter.isObjectEnd() {
2017-02-08 07:46:28 +02:00
break
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type eightFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldDecoder5 *structFieldDecoder
fieldHash6 int32
fieldDecoder6 *structFieldDecoder
fieldHash7 int32
fieldDecoder7 *structFieldDecoder
fieldHash8 int32
fieldDecoder8 *structFieldDecoder
2017-02-08 07:46:28 +02:00
}
2017-06-20 09:11:01 +02:00
func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-02-08 07:46:28 +02:00
if !iter.readObjectStart() {
return
}
for {
switch iter.readFieldHash() {
case decoder.fieldHash1:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder1.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash2:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder2.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash3:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder3.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash4:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder4.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash5:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder5.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash6:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder6.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash7:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder7.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash8:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder8.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
default:
iter.Skip()
}
2017-07-06 10:04:52 +02:00
if iter.isObjectEnd() {
2017-02-08 07:46:28 +02:00
break
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type nineFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldDecoder5 *structFieldDecoder
fieldHash6 int32
fieldDecoder6 *structFieldDecoder
fieldHash7 int32
fieldDecoder7 *structFieldDecoder
fieldHash8 int32
fieldDecoder8 *structFieldDecoder
fieldHash9 int32
fieldDecoder9 *structFieldDecoder
2017-02-08 07:46:28 +02:00
}
2017-06-20 09:11:01 +02:00
func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-02-08 07:46:28 +02:00
if !iter.readObjectStart() {
return
}
for {
switch iter.readFieldHash() {
case decoder.fieldHash1:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder1.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash2:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder2.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash3:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder3.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash4:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder4.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash5:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder5.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash6:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder6.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash7:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder7.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash8:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder8.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash9:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder9.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
default:
iter.Skip()
}
2017-07-06 10:04:52 +02:00
if iter.isObjectEnd() {
2017-02-08 07:46:28 +02:00
break
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type tenFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldDecoder5 *structFieldDecoder
fieldHash6 int32
fieldDecoder6 *structFieldDecoder
fieldHash7 int32
fieldDecoder7 *structFieldDecoder
fieldHash8 int32
fieldDecoder8 *structFieldDecoder
fieldHash9 int32
fieldDecoder9 *structFieldDecoder
fieldHash10 int32
fieldDecoder10 *structFieldDecoder
}
2017-06-20 09:11:01 +02:00
func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-02-08 07:46:28 +02:00
if !iter.readObjectStart() {
return
}
for {
switch iter.readFieldHash() {
case decoder.fieldHash1:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder1.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash2:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder2.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash3:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder3.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash4:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder4.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash5:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder5.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash6:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder6.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash7:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder7.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash8:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder8.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash9:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder9.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
case decoder.fieldHash10:
2017-06-20 09:11:01 +02:00
decoder.fieldDecoder10.Decode(ptr, iter)
2017-02-08 07:46:28 +02:00
default:
iter.Skip()
}
2017-07-06 10:04:52 +02:00
if iter.isObjectEnd() {
2017-02-08 07:46:28 +02:00
break
}
2017-01-07 01:49:50 +02:00
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
}
}
type structFieldDecoder struct {
field *reflect.StructField
fieldDecoder ValDecoder
2017-01-07 01:49:50 +02:00
}
2017-06-20 09:11:01 +02:00
func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-07-09 05:24:26 +02:00
fieldPtr := unsafe.Pointer(uintptr(ptr) + decoder.field.Offset)
decoder.fieldDecoder.Decode(fieldPtr, iter)
2017-01-07 01:49:50 +02:00
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error())
}
}
2017-01-09 13:19:48 +02:00
type structFieldEncoder struct {
field *reflect.StructField
fieldEncoder ValEncoder
2017-03-08 17:38:25 +02:00
omitempty bool
2017-01-09 13:19:48 +02:00
}
2017-06-20 09:11:01 +02:00
func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
2017-07-09 05:24:26 +02:00
fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
encoder.fieldEncoder.Encode(fieldPtr, stream)
2017-01-09 13:19:48 +02:00
if stream.Error != nil && stream.Error != io.EOF {
stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error())
}
}
2017-06-20 09:11:01 +02:00
func (encoder *structFieldEncoder) EncodeInterface(val interface{}, stream *Stream) {
2017-06-20 11:43:47 +02:00
WriteToStream(val, stream, encoder)
2017-01-25 18:25:17 +02:00
}
2017-06-20 09:11:01 +02:00
func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
2017-07-09 05:24:26 +02:00
fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
return encoder.fieldEncoder.IsEmpty(fieldPtr)
2017-03-08 17:38:25 +02:00
}
2017-01-09 13:19:48 +02:00
type structEncoder struct {
onePtrEmbedded bool
onePtrOptimization bool
fields []structFieldTo
2017-06-23 02:21:02 +02:00
}
type structFieldTo struct {
encoder *structFieldEncoder
toName string
2017-01-09 13:19:48 +02:00
}
2017-06-20 09:11:01 +02:00
func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
2017-01-09 13:19:48 +02:00
stream.WriteObjectStart()
2017-03-08 17:38:25 +02:00
isNotFirst := false
2017-06-23 02:21:02 +02:00
for _, field := range encoder.fields {
if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
2017-03-08 17:38:25 +02:00
continue
}
if isNotFirst {
stream.WriteMore()
}
2017-06-23 02:21:02 +02:00
stream.WriteObjectField(field.toName)
field.encoder.Encode(ptr, stream)
2017-03-08 17:38:25 +02:00
isNotFirst = true
2017-01-09 13:19:48 +02:00
}
stream.WriteObjectEnd()
}
2017-06-20 09:11:01 +02:00
func (encoder *structEncoder) EncodeInterface(val interface{}, stream *Stream) {
e := (*emptyInterface)(unsafe.Pointer(&val))
if encoder.onePtrOptimization {
if e.word == nil && encoder.onePtrEmbedded {
stream.WriteObjectStart()
stream.WriteObjectEnd()
return
}
ptr := uintptr(e.word)
e.word = unsafe.Pointer(&ptr)
}
if reflect.TypeOf(val).Kind() == reflect.Ptr {
encoder.Encode(unsafe.Pointer(&e.word), stream)
} else {
encoder.Encode(e.word, stream)
}
2017-01-25 18:25:17 +02:00
}
2017-06-20 09:11:01 +02:00
func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return false
2017-03-08 17:38:25 +02:00
}
2017-01-09 13:19:48 +02:00
type emptyStructEncoder struct {
}
2017-06-20 09:11:01 +02:00
func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
2017-01-09 13:48:57 +02:00
stream.WriteEmptyObject()
2017-01-25 18:25:17 +02:00
}
2017-06-20 09:11:01 +02:00
func (encoder *emptyStructEncoder) EncodeInterface(val interface{}, stream *Stream) {
2017-06-20 11:43:47 +02:00
WriteToStream(val, stream, encoder)
2017-03-08 17:38:25 +02:00
}
2017-06-20 09:11:01 +02:00
func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return false
}