// Getting into an interface is driven completely by the AMQP type, since the interface{} // target is type-neutral. func getInterface(data *C.pn_data_t, v *interface{}) { pnType := C.pn_data_type(data) switch pnType { // Note PN_INVALID is defined outside the enum, older Go versions don't consider it a C.pn_type_t case C.PN_NULL, C.pn_type_t(C.PN_INVALID): // No data. *v = nil case C.PN_BOOL: *v = bool(C.pn_data_get_bool(data)) case C.PN_UBYTE: *v = uint8(C.pn_data_get_ubyte(data)) case C.PN_BYTE: *v = int8(C.pn_data_get_byte(data)) case C.PN_USHORT: *v = uint16(C.pn_data_get_ushort(data)) case C.PN_SHORT: *v = int16(C.pn_data_get_short(data)) case C.PN_UINT: *v = uint32(C.pn_data_get_uint(data)) case C.PN_INT: *v = int32(C.pn_data_get_int(data)) case C.PN_CHAR: *v = uint8(C.pn_data_get_char(data)) case C.PN_ULONG: *v = uint64(C.pn_data_get_ulong(data)) case C.PN_LONG: *v = int64(C.pn_data_get_long(data)) case C.PN_FLOAT: *v = float32(C.pn_data_get_float(data)) case C.PN_DOUBLE: *v = float64(C.pn_data_get_double(data)) case C.PN_BINARY: *v = Binary(goBytes(C.pn_data_get_binary(data))) case C.PN_STRING: *v = goString(C.pn_data_get_string(data)) case C.PN_SYMBOL: *v = Symbol(goString(C.pn_data_get_symbol(data))) case C.PN_MAP: m := make(Map) unmarshal(&m, data) *v = m case C.PN_LIST: l := make(List, 0) unmarshal(&l, data) *v = l default: panic(newUnmarshalError(pnType, v)) } }
// Unmarshal from data into value pointed at by v. func unmarshal(v interface{}, data *C.pn_data_t) { pnType := C.pn_data_type(data) switch v := v.(type) { case *bool: switch pnType { case C.PN_BOOL: *v = bool(C.pn_data_get_bool(data)) default: panic(newUnmarshalError(pnType, v)) } case *int8: switch pnType { case C.PN_CHAR: *v = int8(C.pn_data_get_char(data)) case C.PN_BYTE: *v = int8(C.pn_data_get_byte(data)) default: panic(newUnmarshalError(pnType, v)) } case *uint8: switch pnType { case C.PN_CHAR: *v = uint8(C.pn_data_get_char(data)) case C.PN_UBYTE: *v = uint8(C.pn_data_get_ubyte(data)) default: panic(newUnmarshalError(pnType, v)) } case *int16: switch pnType { case C.PN_CHAR: *v = int16(C.pn_data_get_char(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: panic(newUnmarshalError(pnType, v)) } case *uint16: switch pnType { case C.PN_CHAR: *v = uint16(C.pn_data_get_char(data)) 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: panic(newUnmarshalError(pnType, 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: panic(newUnmarshalError(pnType, 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: panic(newUnmarshalError(pnType, 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: panic(newUnmarshalError(pnType, 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: panic(newUnmarshalError(pnType, 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 unsafe.Sizeof(0) == 8 { *v = int(C.pn_data_get_long(data)) } else { panic(newUnmarshalError(pnType, v)) } default: panic(newUnmarshalError(pnType, 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 unsafe.Sizeof(0) == 8 { *v = uint(C.pn_data_get_ulong(data)) } else { panic(newUnmarshalError(pnType, v)) } default: panic(newUnmarshalError(pnType, v)) } case *float32: switch pnType { case C.PN_FLOAT: *v = float32(C.pn_data_get_float(data)) default: panic(newUnmarshalError(pnType, v)) } 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: panic(newUnmarshalError(pnType, 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: panic(newUnmarshalError(pnType, 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: panic(newUnmarshalError(pnType, v)) } case *Binary: switch pnType { case C.PN_BINARY: *v = Binary(goBytes(C.pn_data_get_binary(data))) default: panic(newUnmarshalError(pnType, v)) } case *Symbol: switch pnType { case C.PN_SYMBOL: *v = Symbol(goBytes(C.pn_data_get_symbol(data))) default: panic(newUnmarshalError(pnType, v)) } case *interface{}: getInterface(data, v) default: if reflect.TypeOf(v).Kind() != reflect.Ptr { panic(newUnmarshalError(pnType, v)) } switch reflect.TypeOf(v).Elem().Kind() { case reflect.Map: getMap(data, v) case reflect.Slice: getList(data, v) default: panic(newUnmarshalError(pnType, v)) } } err := dataError("unmarshaling", data) if err != nil { panic(err) } return }