in go/pkg/amqp/unmarshal.go [291:531]
func unmarshal(v interface{}, data *C.pn_data_t) {
rt := reflect.TypeOf(v)
rv := reflect.ValueOf(v)
panicUnless(v != nil && rt.Kind() == reflect.Ptr && !rv.IsNil(), data, v)
// Check for PN_DESCRIBED first, as described types can unmarshal into any of the Go types.
// An interface{} target is handled in the switch below, even for described types.
if _, isInterface := v.(*interface{}); !isInterface && bool(C.pn_data_is_described(data)) {
getDescribed(data, v)
return
}
// Unmarshal based on the target type
pnType := C.pn_data_type(data)
switch v := v.(type) {
case *bool:
panicUnless(pnType == C.PN_BOOL, data, v)
*v = bool(C.pn_data_get_bool(data))
case *int8:
panicUnless(pnType == C.PN_BYTE, data, v)
*v = int8(C.pn_data_get_byte(data))
case *uint8:
panicUnless(pnType == C.PN_UBYTE, data, v)
*v = uint8(C.pn_data_get_ubyte(data))
case *int16:
switch C.pn_data_type(data) {
case C.PN_BYTE:
*v = int16(C.pn_data_get_byte(data))
case C.PN_SHORT:
*v = int16(C.pn_data_get_short(data))
default:
doPanic(data, v)
}
case *uint16:
switch pnType {
case C.PN_UBYTE:
*v = uint16(C.pn_data_get_ubyte(data))
case C.PN_USHORT:
*v = uint16(C.pn_data_get_ushort(data))
default:
doPanic(data, v)
}
case *int32:
switch pnType {
case C.PN_CHAR:
*v = int32(C.pn_data_get_char(data))
case C.PN_BYTE:
*v = int32(C.pn_data_get_byte(data))
case C.PN_SHORT:
*v = int32(C.pn_data_get_short(data))
case C.PN_INT:
*v = int32(C.pn_data_get_int(data))
default:
doPanic(data, v)
}
case *uint32:
switch pnType {
case C.PN_CHAR:
*v = uint32(C.pn_data_get_char(data))
case C.PN_UBYTE:
*v = uint32(C.pn_data_get_ubyte(data))
case C.PN_USHORT:
*v = uint32(C.pn_data_get_ushort(data))
case C.PN_UINT:
*v = uint32(C.pn_data_get_uint(data))
default:
doPanic(data, v)
}
case *int64:
switch pnType {
case C.PN_CHAR:
*v = int64(C.pn_data_get_char(data))
case C.PN_BYTE:
*v = int64(C.pn_data_get_byte(data))
case C.PN_SHORT:
*v = int64(C.pn_data_get_short(data))
case C.PN_INT:
*v = int64(C.pn_data_get_int(data))
case C.PN_LONG:
*v = int64(C.pn_data_get_long(data))
default:
doPanic(data, v)
}
case *uint64:
switch pnType {
case C.PN_CHAR:
*v = uint64(C.pn_data_get_char(data))
case C.PN_UBYTE:
*v = uint64(C.pn_data_get_ubyte(data))
case C.PN_USHORT:
*v = uint64(C.pn_data_get_ushort(data))
case C.PN_ULONG:
*v = uint64(C.pn_data_get_ulong(data))
default:
doPanic(data, v)
}
case *int:
switch pnType {
case C.PN_CHAR:
*v = int(C.pn_data_get_char(data))
case C.PN_BYTE:
*v = int(C.pn_data_get_byte(data))
case C.PN_SHORT:
*v = int(C.pn_data_get_short(data))
case C.PN_INT:
*v = int(C.pn_data_get_int(data))
case C.PN_LONG:
if intIs64 {
*v = int(C.pn_data_get_long(data))
} else {
doPanic(data, v)
}
default:
doPanic(data, v)
}
case *uint:
switch pnType {
case C.PN_CHAR:
*v = uint(C.pn_data_get_char(data))
case C.PN_UBYTE:
*v = uint(C.pn_data_get_ubyte(data))
case C.PN_USHORT:
*v = uint(C.pn_data_get_ushort(data))
case C.PN_UINT:
*v = uint(C.pn_data_get_uint(data))
case C.PN_ULONG:
if intIs64 {
*v = uint(C.pn_data_get_ulong(data))
} else {
doPanic(data, v)
}
default:
doPanic(data, v)
}
case *float32:
panicUnless(pnType == C.PN_FLOAT, data, v)
*v = float32(C.pn_data_get_float(data))
case *float64:
switch pnType {
case C.PN_FLOAT:
*v = float64(C.pn_data_get_float(data))
case C.PN_DOUBLE:
*v = float64(C.pn_data_get_double(data))
default:
doPanic(data, v)
}
case *string:
switch pnType {
case C.PN_STRING:
*v = goString(C.pn_data_get_string(data))
case C.PN_SYMBOL:
*v = goString(C.pn_data_get_symbol(data))
case C.PN_BINARY:
*v = goString(C.pn_data_get_binary(data))
default:
doPanic(data, v)
}
case *[]byte:
switch pnType {
case C.PN_STRING:
*v = goBytes(C.pn_data_get_string(data))
case C.PN_SYMBOL:
*v = goBytes(C.pn_data_get_symbol(data))
case C.PN_BINARY:
*v = goBytes(C.pn_data_get_binary(data))
default:
doPanic(data, v)
}
return
case *Char:
panicUnless(pnType == C.PN_CHAR, data, v)
*v = Char(C.pn_data_get_char(data))
case *Binary:
panicUnless(pnType == C.PN_BINARY, data, v)
*v = Binary(goBytes(C.pn_data_get_binary(data)))
case *Symbol:
panicUnless(pnType == C.PN_SYMBOL, data, v)
*v = Symbol(goBytes(C.pn_data_get_symbol(data)))
case *time.Time:
panicUnless(pnType == C.PN_TIMESTAMP, data, v)
*v = goTime(C.pn_data_get_timestamp(data))
case *UUID:
panicUnless(pnType == C.PN_UUID, data, v)
pn := C.pn_data_get_uuid(data)
copy((*v)[:], C.GoBytes(unsafe.Pointer(&pn.bytes), 16))
case *AnnotationKey:
panicUnless(pnType == C.PN_ULONG || pnType == C.PN_SYMBOL || pnType == C.PN_STRING, data, v)
unmarshal(&v.value, data)
case *AnyMap:
panicUnless(C.pn_data_type(data) == C.PN_MAP, data, v)
n := int(C.pn_data_get_map(data)) / 2
if cap(*v) < n {
*v = make(AnyMap, n)
}
*v = (*v)[:n]
enter(data, *v)
defer exit(data, *v)
for i := 0; i < n; i++ {
next(data, *v)
unmarshal(&(*v)[i].Key, data)
next(data, *v)
unmarshal(&(*v)[i].Value, data)
}
case *interface{}:
getInterface(data, v)
default: // This is not one of the fixed well-known types, reflect for map and slice types
switch rt.Elem().Kind() {
case reflect.Map:
getMap(data, v)
case reflect.Slice:
getSequence(data, v)
default:
doPanic(data, v)
}
}
}