1
0
mirror of https://github.com/json-iterator/go.git synced 2024-11-30 08:36:43 +02:00
json-iterator/jsoniter_reflect.go

646 lines
16 KiB
Go
Raw Normal View History

2016-12-04 05:06:38 +02:00
package jsoniter
import (
"reflect"
"errors"
2016-12-04 06:27:34 +02:00
"fmt"
"unsafe"
"sync/atomic"
2016-12-04 16:45:20 +02:00
"strings"
2016-12-05 07:20:27 +02:00
"io"
2016-12-04 05:06:38 +02:00
)
type Decoder interface {
2016-12-04 06:27:34 +02:00
decode(ptr unsafe.Pointer, iter *Iterator)
2016-12-04 05:06:38 +02:00
}
type stringDecoder struct {
}
2016-12-04 06:27:34 +02:00
func (decoder *stringDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*string)(ptr)) = iter.ReadString()
}
2016-12-04 15:19:54 +02:00
type intDecoder struct {
}
func (decoder *intDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*int)(ptr)) = iter.ReadInt()
}
2016-12-04 15:32:43 +02:00
type int8Decoder struct {
}
func (decoder *int8Decoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*int8)(ptr)) = iter.ReadInt8()
}
type int16Decoder struct {
}
func (decoder *int16Decoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*int16)(ptr)) = iter.ReadInt16()
}
type int32Decoder struct {
}
func (decoder *int32Decoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*int32)(ptr)) = iter.ReadInt32()
}
type int64Decoder struct {
}
func (decoder *int64Decoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*int64)(ptr)) = iter.ReadInt64()
}
type uintDecoder struct {
}
func (decoder *uintDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uint)(ptr)) = iter.ReadUint()
}
type uint8Decoder struct {
}
func (decoder *uint8Decoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uint8)(ptr)) = iter.ReadUint8()
}
type uint16Decoder struct {
}
func (decoder *uint16Decoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uint16)(ptr)) = iter.ReadUint16()
}
type uint32Decoder struct {
}
func (decoder *uint32Decoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uint32)(ptr)) = iter.ReadUint32()
}
type uint64Decoder struct {
}
func (decoder *uint64Decoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uint64)(ptr)) = iter.ReadUint64()
}
2016-12-04 16:15:12 +02:00
type float32Decoder struct {
}
func (decoder *float32Decoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*float32)(ptr)) = iter.ReadFloat32()
}
type float64Decoder struct {
}
func (decoder *float64Decoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*float64)(ptr)) = iter.ReadFloat64()
}
type boolDecoder struct {
}
func (decoder *boolDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*bool)(ptr)) = iter.ReadBool()
}
2016-12-04 16:45:20 +02:00
type stringNumberDecoder struct {
elemDecoder Decoder
}
func (decoder *stringNumberDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
c := iter.readByte()
if c != '"' {
iter.ReportError("stringNumberDecoder", `expect "`)
return
}
decoder.elemDecoder.decode(ptr, iter)
2016-12-05 07:20:27 +02:00
if iter.Error != nil {
return
}
2016-12-04 16:45:20 +02:00
c = iter.readByte()
if c != '"' {
iter.ReportError("stringNumberDecoder", `expect "`)
return
}
}
2016-12-04 14:50:55 +02:00
type optionalDecoder struct {
2016-12-05 07:20:27 +02:00
valueType reflect.Type
2016-12-04 14:50:55 +02:00
valueDecoder Decoder
2016-12-04 07:13:38 +02:00
}
2016-12-04 14:50:55 +02:00
func (decoder *optionalDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
2016-12-04 07:13:38 +02:00
if iter.ReadNull() {
2016-12-04 14:50:55 +02:00
*((*unsafe.Pointer)(ptr)) = nil
2016-12-04 07:13:38 +02:00
} else {
2016-12-04 14:50:55 +02:00
value := reflect.New(decoder.valueType)
decoder.valueDecoder.decode(unsafe.Pointer(value.Pointer()), iter)
*((*uintptr)(ptr)) = value.Pointer()
2016-12-04 07:13:38 +02:00
}
}
2016-12-08 02:37:20 +02:00
type generalStructDecoder struct {
2016-12-07 02:20:18 +02:00
type_ reflect.Type
2016-12-08 02:37:20 +02:00
fields map[string]*structFieldDecoder
2016-12-04 06:27:34 +02:00
}
2016-12-08 02:37:20 +02:00
func (decoder *generalStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
2016-12-06 05:08:36 +02:00
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
2016-12-08 02:35:03 +02:00
fieldDecoder := decoder.fields[field]
if fieldDecoder == nil {
2016-12-04 06:27:34 +02:00
iter.Skip()
} else {
2016-12-08 02:35:03 +02:00
fieldDecoder.decode(ptr, iter)
2016-12-04 06:27:34 +02:00
}
}
2016-12-05 07:20:27 +02:00
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error())
}
2016-12-04 06:27:34 +02:00
}
2016-12-07 02:20:18 +02:00
type skipDecoder struct {
type_ 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.type_, iter.Error.Error())
}
}
type oneFieldStructDecoder struct {
type_ reflect.Type
fieldName string
2016-12-08 02:37:20 +02:00
fieldDecoder *structFieldDecoder
2016-12-07 02:20:18 +02:00
}
func (decoder *oneFieldStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
if field == decoder.fieldName {
2016-12-08 02:35:03 +02:00
decoder.fieldDecoder.decode(ptr, iter)
2016-12-07 02:20:18 +02:00
} else {
iter.Skip()
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error())
}
}
type twoFieldsStructDecoder struct {
type_ reflect.Type
fieldName1 string
2016-12-08 02:37:20 +02:00
fieldDecoder1 *structFieldDecoder
2016-12-07 02:20:18 +02:00
fieldName2 string
2016-12-08 02:37:20 +02:00
fieldDecoder2 *structFieldDecoder
2016-12-07 02:20:18 +02:00
}
func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
switch field {
case decoder.fieldName1:
2016-12-08 02:35:03 +02:00
decoder.fieldDecoder1.decode(ptr, iter)
2016-12-07 02:20:18 +02:00
case decoder.fieldName2:
2016-12-08 02:35:03 +02:00
decoder.fieldDecoder2.decode(ptr, iter)
2016-12-07 02:20:18 +02:00
default:
iter.Skip()
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error())
}
}
type threeFieldsStructDecoder struct {
type_ reflect.Type
fieldName1 string
2016-12-08 02:37:20 +02:00
fieldDecoder1 *structFieldDecoder
2016-12-07 02:20:18 +02:00
fieldName2 string
2016-12-08 02:37:20 +02:00
fieldDecoder2 *structFieldDecoder
2016-12-07 02:20:18 +02:00
fieldName3 string
2016-12-08 02:37:20 +02:00
fieldDecoder3 *structFieldDecoder
2016-12-07 02:20:18 +02:00
}
func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
switch field {
case decoder.fieldName1:
2016-12-08 02:35:03 +02:00
decoder.fieldDecoder1.decode(ptr, iter)
2016-12-07 02:20:18 +02:00
case decoder.fieldName2:
2016-12-08 02:35:03 +02:00
decoder.fieldDecoder2.decode(ptr, iter)
2016-12-07 02:20:18 +02:00
case decoder.fieldName3:
2016-12-08 02:35:03 +02:00
decoder.fieldDecoder3.decode(ptr, iter)
2016-12-07 02:20:18 +02:00
default:
iter.Skip()
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error())
}
}
type fourFieldsStructDecoder struct {
type_ reflect.Type
fieldName1 string
2016-12-08 02:37:20 +02:00
fieldDecoder1 *structFieldDecoder
2016-12-07 02:20:18 +02:00
fieldName2 string
2016-12-08 02:37:20 +02:00
fieldDecoder2 *structFieldDecoder
2016-12-07 02:20:18 +02:00
fieldName3 string
2016-12-08 02:37:20 +02:00
fieldDecoder3 *structFieldDecoder
2016-12-07 02:20:18 +02:00
fieldName4 string
2016-12-08 02:37:20 +02:00
fieldDecoder4 *structFieldDecoder
2016-12-07 02:20:18 +02:00
}
func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
switch field {
case decoder.fieldName1:
2016-12-08 02:35:03 +02:00
decoder.fieldDecoder1.decode(ptr, iter)
2016-12-07 02:20:18 +02:00
case decoder.fieldName2:
2016-12-08 02:35:03 +02:00
decoder.fieldDecoder2.decode(ptr, iter)
2016-12-07 02:20:18 +02:00
case decoder.fieldName3:
2016-12-08 02:35:03 +02:00
decoder.fieldDecoder3.decode(ptr, iter)
2016-12-07 02:20:18 +02:00
case decoder.fieldName4:
2016-12-08 02:35:03 +02:00
decoder.fieldDecoder4.decode(ptr, iter)
2016-12-07 02:20:18 +02:00
default:
iter.Skip()
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.type_, iter.Error.Error())
}
}
2016-12-08 02:35:03 +02:00
type structFieldDecoder struct {
field *reflect.StructField
2016-12-04 06:27:34 +02:00
fieldDecoder Decoder
}
2016-12-08 02:35:03 +02:00
func (decoder *structFieldDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
fieldPtr := uintptr(ptr) + decoder.field.Offset
decoder.fieldDecoder.decode(unsafe.Pointer(fieldPtr), iter)
2016-12-05 07:20:27 +02:00
if iter.Error != nil && iter.Error != io.EOF {
2016-12-08 02:35:03 +02:00
iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error())
2016-12-05 07:20:27 +02:00
}
2016-12-04 05:06:38 +02:00
}
2016-12-04 14:50:55 +02:00
type sliceDecoder struct {
2016-12-05 07:20:27 +02:00
sliceType reflect.Type
2016-12-04 14:50:55 +02:00
elemType reflect.Type
elemDecoder Decoder
}
// sliceHeader is a safe version of SliceHeader used within this package.
type sliceHeader struct {
Data unsafe.Pointer
Len int
Cap int
}
func (decoder *sliceDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
2016-12-07 02:49:52 +02:00
decoder.doDecode(ptr, iter)
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
}
}
func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
2016-12-04 14:50:55 +02:00
slice := (*sliceHeader)(ptr)
2016-12-07 02:49:52 +02:00
reuseSlice(slice, decoder.sliceType, 4)
if !iter.ReadArray() {
return
}
offset := uintptr(0)
decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter)
if !iter.ReadArray() {
slice.Len = 1
return
}
offset += decoder.elemType.Size()
decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter)
if !iter.ReadArray() {
slice.Len = 2
return
}
offset += decoder.elemType.Size()
decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter)
if !iter.ReadArray() {
slice.Len = 3
return
}
offset += decoder.elemType.Size()
decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter)
slice.Len = 4
2016-12-06 05:08:36 +02:00
for iter.ReadArray() {
2016-12-04 14:50:55 +02:00
growOne(slice, decoder.sliceType, decoder.elemType)
2016-12-07 02:49:52 +02:00
offset += decoder.elemType.Size()
decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter)
2016-12-05 07:20:27 +02:00
}
2016-12-04 14:50:55 +02:00
}
// grow grows the slice s so that it can hold extra more values, allocating
// more capacity if needed. It also returns the old and new slice lengths.
func growOne(slice *sliceHeader, sliceType reflect.Type, elementType reflect.Type) {
newLen := slice.Len + 1
if newLen <= slice.Cap {
slice.Len = newLen
return
}
newCap := slice.Cap
if newCap == 0 {
newCap = 1
} else {
for newCap < newLen {
if slice.Len < 1024 {
newCap += newCap
} else {
newCap += newCap / 4
}
}
}
dst := unsafe.Pointer(reflect.MakeSlice(sliceType, newLen, newCap).Pointer())
originalBytesCount := uintptr(slice.Len) * elementType.Size()
2016-12-05 07:20:27 +02:00
srcPtr := (*[1 << 30]byte)(slice.Data)
dstPtr := (*[1 << 30]byte)(dst)
2016-12-04 14:50:55 +02:00
for i := uintptr(0); i < originalBytesCount; i++ {
dstPtr[i] = srcPtr[i]
}
slice.Len = newLen
slice.Cap = newCap
slice.Data = dst
}
2016-12-07 02:49:52 +02:00
func reuseSlice(slice *sliceHeader, sliceType reflect.Type, expectedCap int) {
if expectedCap <= slice.Cap {
return
}
dst := unsafe.Pointer(reflect.MakeSlice(sliceType, 0, expectedCap).Pointer())
slice.Cap = expectedCap
slice.Data = dst
}
2016-12-04 14:50:55 +02:00
var DECODERS unsafe.Pointer
2016-12-04 05:06:38 +02:00
2016-12-04 14:50:55 +02:00
func addDecoderToCache(cacheKey string, decoder Decoder) {
2016-12-04 07:13:38 +02:00
retry := true
for retry {
2016-12-04 14:50:55 +02:00
ptr := atomic.LoadPointer(&DECODERS)
cache := *(*map[string]Decoder)(ptr)
copy := map[string]Decoder{}
2016-12-04 07:13:38 +02:00
for k, v := range cache {
copy[k] = v
}
copy[cacheKey] = decoder
2016-12-04 14:50:55 +02:00
retry = !atomic.CompareAndSwapPointer(&DECODERS, ptr, unsafe.Pointer(&copy))
2016-12-04 07:13:38 +02:00
}
}
2016-12-04 14:50:55 +02:00
func getDecoderFromCache(cacheKey string) Decoder {
ptr := atomic.LoadPointer(&DECODERS)
cache := *(*map[string]Decoder)(ptr)
2016-12-04 07:13:38 +02:00
return cache[cacheKey]
}
2016-12-05 07:20:27 +02:00
var typeDecoders map[string]Decoder
var fieldDecoders map[string]Decoder
2016-12-04 05:06:38 +02:00
func init() {
2016-12-05 07:20:27 +02:00
typeDecoders = map[string]Decoder{}
fieldDecoders = map[string]Decoder{}
2016-12-04 14:50:55 +02:00
atomic.StorePointer(&DECODERS, unsafe.Pointer(&map[string]Decoder{}))
2016-12-04 06:27:34 +02:00
}
2016-12-05 07:20:27 +02:00
type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
type funcDecoder struct {
func_ DecoderFunc
}
func (decoder *funcDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.func_(ptr, iter)
}
func RegisterTypeDecoder(type_ string, func_ DecoderFunc) {
typeDecoders[type_] = &funcDecoder{func_}
}
func RegisterFieldDecoder(type_ string, field string, func_ DecoderFunc) {
fieldDecoders[fmt.Sprintf("%s/%s", type_, field)] = &funcDecoder{func_}
}
func ClearDecoders() {
typeDecoders = map[string]Decoder{}
fieldDecoders = map[string]Decoder{}
}
2016-12-04 06:27:34 +02:00
// emptyInterface is the header for an interface{} value.
type emptyInterface struct {
typ *struct{}
word unsafe.Pointer
2016-12-04 05:06:38 +02:00
}
func (iter *Iterator) Read(obj interface{}) {
type_ := reflect.TypeOf(obj)
2016-12-04 14:50:55 +02:00
cacheKey := type_.String()
cachedDecoder := getDecoderFromCache(cacheKey)
if cachedDecoder == nil {
decoder, err := decoderOfType(type_)
if err != nil {
iter.Error = err
return
}
cachedDecoder = decoder
addDecoderToCache(cacheKey, decoder)
2016-12-04 05:06:38 +02:00
}
2016-12-04 06:27:34 +02:00
e := (*emptyInterface)(unsafe.Pointer(&obj))
2016-12-04 14:50:55 +02:00
cachedDecoder.decode(e.word, iter)
2016-12-04 06:27:34 +02:00
}
type prefix string
func (p prefix) addTo(decoder Decoder, err error) (Decoder, error) {
if err != nil {
return nil, fmt.Errorf("%s: %s", p, err.Error())
}
return decoder, err
2016-12-04 05:06:38 +02:00
}
func decoderOfType(type_ reflect.Type) (Decoder, error) {
switch type_.Kind() {
case reflect.Ptr:
2016-12-04 06:27:34 +02:00
return prefix("ptr").addTo(decoderOfPtr(type_.Elem()))
2016-12-04 05:06:38 +02:00
default:
return nil, errors.New("expect ptr")
}
}
func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
2016-12-05 07:20:27 +02:00
typeDecoder := typeDecoders[type_.String()]
if typeDecoder != nil {
return typeDecoder, nil
}
2016-12-04 05:06:38 +02:00
switch type_.Kind() {
case reflect.String:
2016-12-04 15:19:54 +02:00
return &stringDecoder{}, nil
case reflect.Int:
return &intDecoder{}, nil
2016-12-04 15:32:43 +02:00
case reflect.Int8:
return &int8Decoder{}, nil
case reflect.Int16:
return &int16Decoder{}, nil
case reflect.Int32:
return &int32Decoder{}, nil
case reflect.Int64:
return &int64Decoder{}, nil
case reflect.Uint:
return &uintDecoder{}, nil
case reflect.Uint8:
return &uint8Decoder{}, nil
case reflect.Uint16:
return &uint16Decoder{}, nil
case reflect.Uint32:
return &uint32Decoder{}, nil
case reflect.Uint64:
return &uint64Decoder{}, nil
2016-12-04 16:15:12 +02:00
case reflect.Float32:
return &float32Decoder{}, nil
case reflect.Float64:
return &float64Decoder{}, nil
case reflect.Bool:
return &boolDecoder{}, nil
2016-12-04 06:27:34 +02:00
case reflect.Struct:
return decoderOfStruct(type_)
2016-12-04 07:13:38 +02:00
case reflect.Slice:
2016-12-04 15:19:54 +02:00
return prefix("[slice]").addTo(decoderOfSlice(type_))
2016-12-04 07:13:38 +02:00
case reflect.Ptr:
2016-12-04 15:19:54 +02:00
return prefix("[optional]").addTo(decoderOfOptional(type_.Elem()))
2016-12-04 07:13:38 +02:00
default:
2016-12-04 15:19:54 +02:00
return nil, fmt.Errorf("unsupported type: %v", type_)
2016-12-04 07:13:38 +02:00
}
}
func decoderOfOptional(type_ reflect.Type) (Decoder, error) {
2016-12-04 15:19:54 +02:00
decoder, err := decoderOfPtr(type_)
if err != nil {
return nil, err
2016-12-04 05:06:38 +02:00
}
2016-12-04 15:19:54 +02:00
return &optionalDecoder{type_, decoder}, nil
2016-12-04 05:06:38 +02:00
}
2016-12-04 06:27:34 +02:00
func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
2016-12-08 02:37:20 +02:00
fields := map[string]*structFieldDecoder{}
2016-12-04 14:50:55 +02:00
for i := 0; i < type_.NumField(); i++ {
field := type_.Field(i)
2016-12-05 07:20:27 +02:00
fieldDecoderKey := fmt.Sprintf("%s/%s", type_.String(), field.Name)
decoder := fieldDecoders[fieldDecoderKey]
2016-12-04 16:45:20 +02:00
tagParts := strings.Split(field.Tag.Get("json"), ",")
jsonFieldName := tagParts[0]
if jsonFieldName == "" {
jsonFieldName = field.Name
}
2016-12-05 07:20:27 +02:00
if decoder == nil {
var err error
decoder, err = decoderOfPtr(field.Type)
if err != nil {
return prefix(fmt.Sprintf("{%s}", field.Name)).addTo(decoder, err)
}
2016-12-04 06:27:34 +02:00
}
2016-12-04 16:45:20 +02:00
if len(tagParts) > 1 && tagParts[1] == "string" {
decoder = &stringNumberDecoder{decoder}
}
if jsonFieldName != "-" {
2016-12-08 02:35:03 +02:00
fields[jsonFieldName] = &structFieldDecoder{&field, decoder}
2016-12-04 16:45:20 +02:00
}
2016-12-04 06:27:34 +02:00
}
2016-12-07 02:20:18 +02:00
switch len(fields) {
case 0:
return &skipDecoder{type_}, nil
case 1:
2016-12-08 02:35:03 +02:00
for fieldName, fieldDecoder := range fields {
return &oneFieldStructDecoder{type_, fieldName, fieldDecoder}, nil
2016-12-07 02:20:18 +02:00
}
case 2:
var fieldName1 string
var fieldName2 string
2016-12-08 02:37:20 +02:00
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
2016-12-08 02:35:03 +02:00
for fieldName, fieldDecoder := range fields {
2016-12-07 02:20:18 +02:00
if fieldName1 == "" {
fieldName1 = fieldName
2016-12-08 02:35:03 +02:00
fieldDecoder1 = fieldDecoder
2016-12-07 02:20:18 +02:00
} else {
fieldName2 = fieldName
2016-12-08 02:35:03 +02:00
fieldDecoder2 = fieldDecoder
2016-12-07 02:20:18 +02:00
}
}
2016-12-08 02:35:03 +02:00
return &twoFieldsStructDecoder{type_, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2}, nil
2016-12-07 02:20:18 +02:00
case 3:
var fieldName1 string
var fieldName2 string
var fieldName3 string
2016-12-08 02:37:20 +02:00
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
2016-12-08 02:35:03 +02:00
for fieldName, fieldDecoder := range fields {
2016-12-07 02:20:18 +02:00
if fieldName1 == "" {
fieldName1 = fieldName
2016-12-08 02:35:03 +02:00
fieldDecoder1 = fieldDecoder
2016-12-07 02:20:18 +02:00
} else if fieldName2 == "" {
fieldName2 = fieldName
2016-12-08 02:35:03 +02:00
fieldDecoder2 = fieldDecoder
2016-12-07 02:20:18 +02:00
} else {
fieldName3 = fieldName
2016-12-08 02:35:03 +02:00
fieldDecoder3 = fieldDecoder
2016-12-07 02:20:18 +02:00
}
}
return &threeFieldsStructDecoder{type_,
2016-12-08 02:35:03 +02:00
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil
2016-12-07 02:20:18 +02:00
case 4:
var fieldName1 string
var fieldName2 string
var fieldName3 string
var fieldName4 string
2016-12-08 02:37:20 +02:00
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
2016-12-08 02:35:03 +02:00
for fieldName, fieldDecoder := range fields {
2016-12-07 02:20:18 +02:00
if fieldName1 == "" {
fieldName1 = fieldName
2016-12-08 02:35:03 +02:00
fieldDecoder1 = fieldDecoder
2016-12-07 02:20:18 +02:00
} else if fieldName2 == "" {
fieldName2 = fieldName
2016-12-08 02:35:03 +02:00
fieldDecoder2 = fieldDecoder
2016-12-07 02:20:18 +02:00
} else if fieldName3 == "" {
fieldName3 = fieldName
2016-12-08 02:35:03 +02:00
fieldDecoder3 = fieldDecoder
2016-12-07 02:20:18 +02:00
} else {
fieldName4 = fieldName
2016-12-08 02:35:03 +02:00
fieldDecoder4 = fieldDecoder
2016-12-07 02:20:18 +02:00
}
}
return &fourFieldsStructDecoder{type_,
2016-12-08 02:35:03 +02:00
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4}, nil
2016-12-07 02:20:18 +02:00
}
2016-12-08 02:37:20 +02:00
return &generalStructDecoder{type_, fields}, nil
2016-12-04 06:27:34 +02:00
}
2016-12-04 07:13:38 +02:00
func decoderOfSlice(type_ reflect.Type) (Decoder, error) {
2016-12-04 14:50:55 +02:00
decoder, err := decoderOfPtr(type_.Elem())
if err != nil {
2016-12-04 15:19:54 +02:00
return nil, err
2016-12-04 14:50:55 +02:00
}
return &sliceDecoder{type_, type_.Elem(), decoder}, nil
2016-12-04 06:27:34 +02:00
}