2017-01-07 01:49:50 +02:00
|
|
|
package jsoniter
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"fmt"
|
|
|
|
"reflect"
|
|
|
|
"unsafe"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2017-01-09 13:19:48 +02:00
|
|
|
|
|
|
|
func encoderOfStruct(typ reflect.Type) (Encoder, error) {
|
|
|
|
structEncoder_ := &structEncoder{}
|
|
|
|
for i := 0; i < typ.NumField(); i++ {
|
|
|
|
field := typ.Field(i)
|
|
|
|
var fieldNames []string
|
|
|
|
for _, extension := range extensions {
|
|
|
|
alternativeFieldNames, _ := extension(typ, &field)
|
|
|
|
if alternativeFieldNames != nil {
|
|
|
|
fieldNames = alternativeFieldNames
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tagParts := strings.Split(field.Tag.Get("json"), ",")
|
|
|
|
// if fieldNames set by extension, use theirs, otherwise try tags
|
|
|
|
if fieldNames == nil {
|
|
|
|
/// tagParts[0] always present, even if no tags
|
|
|
|
switch tagParts[0] {
|
|
|
|
case "":
|
|
|
|
fieldNames = []string{field.Name}
|
|
|
|
case "-":
|
|
|
|
fieldNames = []string{}
|
|
|
|
default:
|
|
|
|
fieldNames = []string{tagParts[0]}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
encoder, err := encoderOfType(field.Type)
|
|
|
|
if err != nil {
|
|
|
|
return prefix(fmt.Sprintf("{%s}", field.Name)).addToEncoder(encoder, err)
|
|
|
|
}
|
2017-02-03 12:44:54 +02:00
|
|
|
// map is stored as pointer in the struct
|
|
|
|
// but if struct only has one map, it is inlined
|
|
|
|
if field.Type.Kind() == reflect.Map && typ.NumField() > 1 {
|
|
|
|
encoder = &optionalEncoder{field.Type, encoder}
|
|
|
|
}
|
2017-01-09 13:19:48 +02:00
|
|
|
for _, fieldName := range fieldNames {
|
|
|
|
if structEncoder_.firstField == nil {
|
|
|
|
structEncoder_.firstField = &structFieldEncoder{&field, fieldName, encoder}
|
|
|
|
} else {
|
|
|
|
structEncoder_.fields = append(structEncoder_.fields, &structFieldEncoder{&field, fieldName, encoder})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if structEncoder_.firstField == nil {
|
|
|
|
return &emptyStructEncoder{}, nil
|
|
|
|
}
|
|
|
|
return structEncoder_, nil
|
|
|
|
}
|
|
|
|
|
2017-01-07 01:49:50 +02:00
|
|
|
func decoderOfStruct(typ reflect.Type) (Decoder, error) {
|
|
|
|
fields := map[string]*structFieldDecoder{}
|
|
|
|
for i := 0; i < typ.NumField(); i++ {
|
|
|
|
field := typ.Field(i)
|
|
|
|
fieldDecoderKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
|
|
|
|
var fieldNames []string
|
|
|
|
for _, extension := range extensions {
|
|
|
|
alternativeFieldNames, fun := extension(typ, &field)
|
|
|
|
if alternativeFieldNames != nil {
|
|
|
|
fieldNames = alternativeFieldNames
|
|
|
|
}
|
|
|
|
if fun != nil {
|
|
|
|
fieldDecoders[fieldDecoderKey] = &funcDecoder{fun}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
decoder := fieldDecoders[fieldDecoderKey]
|
|
|
|
tagParts := strings.Split(field.Tag.Get("json"), ",")
|
|
|
|
// if fieldNames set by extension, use theirs, otherwise try tags
|
|
|
|
if fieldNames == nil {
|
|
|
|
/// tagParts[0] always present, even if no tags
|
|
|
|
switch tagParts[0] {
|
|
|
|
case "":
|
|
|
|
fieldNames = []string{field.Name}
|
|
|
|
case "-":
|
|
|
|
fieldNames = []string{}
|
|
|
|
default:
|
|
|
|
fieldNames = []string{tagParts[0]}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if decoder == nil {
|
|
|
|
var err error
|
2017-01-09 11:47:21 +02:00
|
|
|
decoder, err = decoderOfType(field.Type)
|
2017-01-07 01:49:50 +02:00
|
|
|
if err != nil {
|
2017-01-09 13:19:48 +02:00
|
|
|
return prefix(fmt.Sprintf("{%s}", field.Name)).addToDecoder(decoder, err)
|
2017-01-07 01:49:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(tagParts) > 1 && tagParts[1] == "string" {
|
|
|
|
decoder = &stringNumberDecoder{decoder}
|
|
|
|
}
|
|
|
|
for _, fieldName := range fieldNames {
|
|
|
|
fields[fieldName] = &structFieldDecoder{&field, decoder}
|
|
|
|
}
|
|
|
|
}
|
2017-02-08 07:46:28 +02:00
|
|
|
return createStructDecoder(typ, fields)
|
|
|
|
}
|
|
|
|
|
|
|
|
func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (Decoder, error) {
|
|
|
|
knownHash := map[int32]struct{}{
|
|
|
|
0: struct{}{},
|
|
|
|
}
|
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,
|
|
|
|
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil
|
|
|
|
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,
|
|
|
|
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,
|
|
|
|
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
|
|
|
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil
|
|
|
|
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,
|
|
|
|
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
|
|
|
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil
|
|
|
|
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,
|
|
|
|
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
|
|
|
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
|
|
|
|
fieldName7, fieldDecoder7}, nil
|
|
|
|
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,
|
|
|
|
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
|
|
|
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
|
|
|
|
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil
|
|
|
|
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,
|
|
|
|
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
|
|
|
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
|
|
|
|
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil
|
|
|
|
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,
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *generalStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
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 {
|
|
|
|
fieldDecoder.decode(ptr, iter)
|
|
|
|
}
|
|
|
|
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 {
|
|
|
|
fieldDecoder.decode(ptr, iter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *skipDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *oneFieldStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
if !iter.readObjectStart() {
|
|
|
|
return
|
|
|
|
}
|
2017-02-08 07:46:28 +02:00
|
|
|
for {
|
|
|
|
if iter.readFieldHash() == decoder.fieldHash {
|
2017-01-07 01:49:50 +02:00
|
|
|
decoder.fieldDecoder.decode(ptr, iter)
|
|
|
|
} else {
|
|
|
|
iter.Skip()
|
|
|
|
}
|
2017-02-08 07:46:28 +02:00
|
|
|
if iter.nextToken() != ',' {
|
|
|
|
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 {
|
2017-02-08 07:46:28 +02:00
|
|
|
typ reflect.Type
|
|
|
|
fieldHash1 int32
|
|
|
|
fieldDecoder1 *structFieldDecoder
|
|
|
|
fieldHash2 int32
|
|
|
|
fieldDecoder2 *structFieldDecoder
|
2017-01-07 01:49:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
if !iter.readObjectStart() {
|
|
|
|
return
|
|
|
|
}
|
2017-02-08 07:46:28 +02:00
|
|
|
for {
|
|
|
|
switch iter.readFieldHash() {
|
|
|
|
case decoder.fieldHash1:
|
2017-01-07 01:49:50 +02:00
|
|
|
decoder.fieldDecoder1.decode(ptr, iter)
|
2017-02-08 07:46:28 +02:00
|
|
|
case decoder.fieldHash2:
|
2017-01-07 01:49:50 +02:00
|
|
|
decoder.fieldDecoder2.decode(ptr, iter)
|
|
|
|
default:
|
|
|
|
iter.Skip()
|
|
|
|
}
|
2017-02-08 07:46:28 +02:00
|
|
|
if iter.nextToken() != ',' {
|
|
|
|
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 {
|
2017-02-08 07:46:28 +02:00
|
|
|
typ reflect.Type
|
|
|
|
fieldHash1 int32
|
|
|
|
fieldDecoder1 *structFieldDecoder
|
|
|
|
fieldHash2 int32
|
|
|
|
fieldDecoder2 *structFieldDecoder
|
|
|
|
fieldHash3 int32
|
|
|
|
fieldDecoder3 *structFieldDecoder
|
2017-01-07 01:49:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
if !iter.readObjectStart() {
|
|
|
|
return
|
|
|
|
}
|
2017-02-08 07:46:28 +02:00
|
|
|
for {
|
|
|
|
switch iter.readFieldHash() {
|
|
|
|
case decoder.fieldHash1:
|
2017-01-07 01:49:50 +02:00
|
|
|
decoder.fieldDecoder1.decode(ptr, iter)
|
2017-02-08 07:46:28 +02:00
|
|
|
case decoder.fieldHash2:
|
2017-01-07 01:49:50 +02:00
|
|
|
decoder.fieldDecoder2.decode(ptr, iter)
|
2017-02-08 07:46:28 +02:00
|
|
|
case decoder.fieldHash3:
|
2017-01-07 01:49:50 +02:00
|
|
|
decoder.fieldDecoder3.decode(ptr, iter)
|
|
|
|
default:
|
|
|
|
iter.Skip()
|
|
|
|
}
|
2017-02-08 07:46:28 +02:00
|
|
|
if iter.nextToken() != ',' {
|
|
|
|
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 {
|
2017-02-08 07:46:28 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
if !iter.readObjectStart() {
|
|
|
|
return
|
|
|
|
}
|
2017-02-08 07:46:28 +02:00
|
|
|
for {
|
|
|
|
switch iter.readFieldHash() {
|
|
|
|
case decoder.fieldHash1:
|
|
|
|
decoder.fieldDecoder1.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash2:
|
|
|
|
decoder.fieldDecoder2.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash3:
|
|
|
|
decoder.fieldDecoder3.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash4:
|
|
|
|
decoder.fieldDecoder4.decode(ptr, iter)
|
|
|
|
default:
|
|
|
|
iter.Skip()
|
|
|
|
}
|
|
|
|
if iter.nextToken() != ',' {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *fiveFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
if !iter.readObjectStart() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for {
|
|
|
|
switch iter.readFieldHash() {
|
|
|
|
case decoder.fieldHash1:
|
|
|
|
decoder.fieldDecoder1.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash2:
|
|
|
|
decoder.fieldDecoder2.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash3:
|
|
|
|
decoder.fieldDecoder3.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash4:
|
|
|
|
decoder.fieldDecoder4.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash5:
|
|
|
|
decoder.fieldDecoder5.decode(ptr, iter)
|
|
|
|
default:
|
|
|
|
iter.Skip()
|
|
|
|
}
|
|
|
|
if iter.nextToken() != ',' {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *sixFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
if !iter.readObjectStart() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for {
|
|
|
|
switch iter.readFieldHash() {
|
|
|
|
case decoder.fieldHash1:
|
2017-01-07 01:49:50 +02:00
|
|
|
decoder.fieldDecoder1.decode(ptr, iter)
|
2017-02-08 07:46:28 +02:00
|
|
|
case decoder.fieldHash2:
|
2017-01-07 01:49:50 +02:00
|
|
|
decoder.fieldDecoder2.decode(ptr, iter)
|
2017-02-08 07:46:28 +02:00
|
|
|
case decoder.fieldHash3:
|
2017-01-07 01:49:50 +02:00
|
|
|
decoder.fieldDecoder3.decode(ptr, iter)
|
2017-02-08 07:46:28 +02:00
|
|
|
case decoder.fieldHash4:
|
2017-01-07 01:49:50 +02:00
|
|
|
decoder.fieldDecoder4.decode(ptr, iter)
|
2017-02-08 07:46:28 +02:00
|
|
|
case decoder.fieldHash5:
|
|
|
|
decoder.fieldDecoder5.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash6:
|
|
|
|
decoder.fieldDecoder6.decode(ptr, iter)
|
2017-01-07 01:49:50 +02:00
|
|
|
default:
|
|
|
|
iter.Skip()
|
|
|
|
}
|
2017-02-08 07:46:28 +02:00
|
|
|
if iter.nextToken() != ',' {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *sevenFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
if !iter.readObjectStart() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for {
|
|
|
|
switch iter.readFieldHash() {
|
|
|
|
case decoder.fieldHash1:
|
|
|
|
decoder.fieldDecoder1.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash2:
|
|
|
|
decoder.fieldDecoder2.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash3:
|
|
|
|
decoder.fieldDecoder3.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash4:
|
|
|
|
decoder.fieldDecoder4.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash5:
|
|
|
|
decoder.fieldDecoder5.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash6:
|
|
|
|
decoder.fieldDecoder6.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash7:
|
|
|
|
decoder.fieldDecoder7.decode(ptr, iter)
|
|
|
|
default:
|
|
|
|
iter.Skip()
|
|
|
|
}
|
|
|
|
if iter.nextToken() != ',' {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *eightFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
if !iter.readObjectStart() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for {
|
|
|
|
switch iter.readFieldHash() {
|
|
|
|
case decoder.fieldHash1:
|
|
|
|
decoder.fieldDecoder1.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash2:
|
|
|
|
decoder.fieldDecoder2.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash3:
|
|
|
|
decoder.fieldDecoder3.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash4:
|
|
|
|
decoder.fieldDecoder4.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash5:
|
|
|
|
decoder.fieldDecoder5.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash6:
|
|
|
|
decoder.fieldDecoder6.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash7:
|
|
|
|
decoder.fieldDecoder7.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash8:
|
|
|
|
decoder.fieldDecoder8.decode(ptr, iter)
|
|
|
|
default:
|
|
|
|
iter.Skip()
|
|
|
|
}
|
|
|
|
if iter.nextToken() != ',' {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *nineFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
if !iter.readObjectStart() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for {
|
|
|
|
switch iter.readFieldHash() {
|
|
|
|
case decoder.fieldHash1:
|
|
|
|
decoder.fieldDecoder1.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash2:
|
|
|
|
decoder.fieldDecoder2.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash3:
|
|
|
|
decoder.fieldDecoder3.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash4:
|
|
|
|
decoder.fieldDecoder4.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash5:
|
|
|
|
decoder.fieldDecoder5.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash6:
|
|
|
|
decoder.fieldDecoder6.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash7:
|
|
|
|
decoder.fieldDecoder7.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash8:
|
|
|
|
decoder.fieldDecoder8.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash9:
|
|
|
|
decoder.fieldDecoder9.decode(ptr, iter)
|
|
|
|
default:
|
|
|
|
iter.Skip()
|
|
|
|
}
|
|
|
|
if iter.nextToken() != ',' {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *tenFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
if !iter.readObjectStart() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for {
|
|
|
|
switch iter.readFieldHash() {
|
|
|
|
case decoder.fieldHash1:
|
|
|
|
decoder.fieldDecoder1.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash2:
|
|
|
|
decoder.fieldDecoder2.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash3:
|
|
|
|
decoder.fieldDecoder3.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash4:
|
|
|
|
decoder.fieldDecoder4.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash5:
|
|
|
|
decoder.fieldDecoder5.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash6:
|
|
|
|
decoder.fieldDecoder6.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash7:
|
|
|
|
decoder.fieldDecoder7.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash8:
|
|
|
|
decoder.fieldDecoder8.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash9:
|
|
|
|
decoder.fieldDecoder9.decode(ptr, iter)
|
|
|
|
case decoder.fieldHash10:
|
|
|
|
decoder.fieldDecoder10.decode(ptr, iter)
|
|
|
|
default:
|
|
|
|
iter.Skip()
|
|
|
|
}
|
|
|
|
if iter.nextToken() != ',' {
|
|
|
|
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 Decoder
|
|
|
|
}
|
|
|
|
|
|
|
|
func (decoder *structFieldDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
fieldPtr := uintptr(ptr) + decoder.field.Offset
|
|
|
|
decoder.fieldDecoder.decode(unsafe.Pointer(fieldPtr), iter)
|
|
|
|
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
|
|
|
|
fieldName string
|
|
|
|
fieldEncoder Encoder
|
|
|
|
}
|
|
|
|
|
|
|
|
func (encoder *structFieldEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
|
|
|
fieldPtr := uintptr(ptr) + encoder.field.Offset
|
|
|
|
stream.WriteObjectField(encoder.fieldName)
|
|
|
|
encoder.fieldEncoder.encode(unsafe.Pointer(fieldPtr), stream)
|
|
|
|
if stream.Error != nil && stream.Error != io.EOF {
|
|
|
|
stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-25 18:25:17 +02:00
|
|
|
func (encoder *structFieldEncoder) encodeInterface(val interface{}, stream *Stream) {
|
|
|
|
WriteToStream(val, stream, encoder)
|
|
|
|
}
|
|
|
|
|
2017-01-09 13:19:48 +02:00
|
|
|
|
|
|
|
type structEncoder struct {
|
|
|
|
firstField *structFieldEncoder
|
|
|
|
fields []*structFieldEncoder
|
|
|
|
}
|
|
|
|
|
|
|
|
func (encoder *structEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
|
|
|
stream.WriteObjectStart()
|
|
|
|
encoder.firstField.encode(ptr, stream)
|
|
|
|
for _, field := range encoder.fields {
|
|
|
|
stream.WriteMore()
|
|
|
|
field.encode(ptr, stream)
|
|
|
|
}
|
|
|
|
stream.WriteObjectEnd()
|
|
|
|
}
|
|
|
|
|
2017-01-25 18:25:17 +02:00
|
|
|
func (encoder *structEncoder) encodeInterface(val interface{}, stream *Stream) {
|
|
|
|
WriteToStream(val, stream, encoder)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-09 13:19:48 +02:00
|
|
|
type emptyStructEncoder struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
func (encoder *emptyStructEncoder) encodeInterface(val interface{}, stream *Stream) {
|
|
|
|
WriteToStream(val, stream, encoder)
|
2017-01-09 13:19:48 +02:00
|
|
|
}
|