1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
package encoding
import (
"errors"
"reflect"
"runtime"
"sync"
)
var byteSliceType = reflect.TypeOf([]byte(nil))
type decoderFunc func(dv reflect.Value, sv reflect.Value) error
// Decode decodes map[string]interface{} into a struct. The first parameter
// must be a pointer.
func Decode(dst interface{}, src interface{}) (err error) {
return decode(dst, src, true)
}
func Merge(dst interface{}, src interface{}) (err error) {
return decode(dst, src, false)
}
func decode(dst interface{}, src interface{}, blank bool) (err error) {
defer func() {
if r := recover(); r != nil {
if _, ok := r.(runtime.Error); ok {
panic(r)
}
if v, ok := r.(string); ok {
err = errors.New(v)
} else {
err = r.(error)
}
}
}()
dv := reflect.ValueOf(dst)
sv := reflect.ValueOf(src)
if dv.Kind() != reflect.Ptr {
return &DecodeTypeError{
DestType: dv.Type(),
SrcType: sv.Type(),
Reason: "must be a pointer",
}
}
dv = dv.Elem()
if !dv.CanAddr() {
return &DecodeTypeError{
DestType: dv.Type(),
SrcType: sv.Type(),
Reason: "must be addressable",
}
}
return decodeValue(dv, sv, blank)
}
// decodeValue decodes the source value into the destination value
func decodeValue(dv, sv reflect.Value, blank bool) error {
return valueDecoder(dv, sv, blank)(dv, sv)
}
type decoderCacheKey struct {
dt, st reflect.Type
}
var decoderCache struct {
sync.RWMutex
m map[decoderCacheKey]decoderFunc
}
func valueDecoder(dv, sv reflect.Value, blank bool) decoderFunc {
if !sv.IsValid() {
return invalidValueDecoder
}
if dv.IsValid() {
dv = indirect(dv, false)
if sv.Kind() == reflect.Ptr {
sv = indirect(sv, false)
dv.Set(sv)
} else if blank {
dv.Set(reflect.Zero(dv.Type()))
}
}
return typeDecoder(dv.Type(), sv.Type(), blank)
}
func typeDecoder(dt, st reflect.Type, blank bool) decoderFunc {
decoderCache.RLock()
f := decoderCache.m[decoderCacheKey{dt, st}]
decoderCache.RUnlock()
if f != nil {
return f
}
// To deal with recursive types, populate the map with an
// indirect func before we build it. This type waits on the
// real func (f) to be ready and then calls it. This indirect
// func is only used for recursive types.
decoderCache.Lock()
var wg sync.WaitGroup
wg.Add(1)
decoderCache.m[decoderCacheKey{dt, st}] = func(dv, sv reflect.Value) error {
wg.Wait()
return f(dv, sv)
}
decoderCache.Unlock()
// Compute fields without lock.
// Might duplicate effort but won't hold other computations back.
f = newTypeDecoder(dt, st, blank)
wg.Done()
decoderCache.Lock()
decoderCache.m[decoderCacheKey{dt, st}] = f
decoderCache.Unlock()
return f
}
// indirect walks down v allocating pointers as needed,
// until it gets to a non-pointer.
func indirect(v reflect.Value, decodeNull bool) reflect.Value {
// If v is a named type and is addressable,
// start with its address, so that if the type has pointer methods,
// we find them.
if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
v = v.Addr()
}
for {
// Load value from interface, but only if the result will be
// usefully addressable.
if v.Kind() == reflect.Interface && !v.IsNil() {
e := v.Elem()
if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodeNull || e.Elem().Kind() == reflect.Ptr) {
v = e
continue
}
}
if v.Kind() != reflect.Ptr {
break
}
if v.IsNil() {
v.Set(reflect.New(v.Type().Elem()))
}
v = v.Elem()
}
return v
}
|