// get into map pointed at by v func getMap(data *C.pn_data_t, v interface{}) { mapValue := reflect.ValueOf(v).Elem() mapValue.Set(reflect.MakeMap(mapValue.Type())) // Clear the map switch pnType := C.pn_data_type(data); pnType { case C.PN_MAP: count := int(C.pn_data_get_map(data)) if bool(C.pn_data_enter(data)) { defer C.pn_data_exit(data) for i := 0; i < count/2; i++ { if bool(C.pn_data_next(data)) { key := reflect.New(mapValue.Type().Key()) unmarshal(key.Interface(), data) if bool(C.pn_data_next(data)) { val := reflect.New(mapValue.Type().Elem()) unmarshal(val.Interface(), data) mapValue.SetMapIndex(key.Elem(), val.Elem()) } } } } // Note PN_INVALID is defined outside the enum, older Go versions don't consider it a C.pn_type_t case C.pn_type_t(C.PN_INVALID): // Leave the map empty default: panic(newUnmarshalError(pnType, v)) } }
func (t Type) String() string { switch C.pn_type_t(t) { case C.PN_NULL: return "null" case C.PN_BOOL: return "bool" case C.PN_UBYTE: return "ubyte" case C.PN_BYTE: return "byte" case C.PN_USHORT: return "ushort" case C.PN_SHORT: return "short" case C.PN_CHAR: return "char" case C.PN_UINT: return "uint" case C.PN_INT: return "int" case C.PN_ULONG: return "ulong" case C.PN_LONG: return "long" case C.PN_TIMESTAMP: return "timestamp" case C.PN_FLOAT: return "float" case C.PN_DOUBLE: return "double" case C.PN_DECIMAL32: return "decimal32" case C.PN_DECIMAL64: return "decimal64" case C.PN_DECIMAL128: return "decimal128" case C.PN_UUID: return "uuid" case C.PN_BINARY: return "binary" case C.PN_STRING: return "string" case C.PN_SYMBOL: return "symbol" case C.PN_DESCRIBED: return "described" case C.PN_ARRAY: return "array" case C.PN_LIST: return "list" case C.PN_MAP: return "map" case C.PN_INVALID: return "no-data" default: return fmt.Sprintf("unknown-type(%d)", t) } }
// 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)) } }
func newUnmarshalError(pnType C.pn_type_t, v interface{}) *UnmarshalError { return &UnmarshalError{C.pn_type_t(pnType).String(), reflect.TypeOf(v)} }