in codec.go [275:341]
func SetValue(dest, v reflect.Value) {
// zero value not need to set
if !v.IsValid() {
return
}
vType := v.Type()
destType := dest.Type()
// for most cases, the types are the same and can set the value directly.
if dest.CanSet() && destType == vType {
dest.Set(v)
return
}
// check whether the v is a ref holder
if vType == _refHolderPtrType {
h := v.Interface().(*_refHolder)
h.add(dest)
return
}
vRawType, vPtrDepth := UnpackType(vType)
// unpack to the root addressable value, so that to set the value.
dest = UnpackToRootAddressableValue(dest)
destType = dest.Type()
destRawType, destPtrDepth := UnpackType(destType)
// it can set the value directly if the raw types are of the same type.
if destRawType == vRawType {
if destPtrDepth > vPtrDepth {
// pack to the same level of dest
for i := 0; i < destPtrDepth-vPtrDepth; i++ {
v = PackPtr(v)
}
} else if destPtrDepth < vPtrDepth {
// unpack to the same level of dest
for i := 0; i < vPtrDepth-destPtrDepth; i++ {
v = v.Elem()
}
}
dest.Set(v)
return
}
switch destType.Kind() {
case reflect.Float32, reflect.Float64:
dest.SetFloat(v.Float())
return
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
dest.SetInt(v.Int())
return
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
// hessian only support 64-bit signed long integer.
dest.SetUint(uint64(v.Int()))
return
case reflect.Ptr:
SetValueToPtrDest(dest, v)
return
default:
// It's ok when the dest is an interface{}, while the v is a pointer.
dest.Set(v)
}
}