// 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()) } } } } case C.PN_INVALID: // Leave the map empty default: panic(newUnmarshalError(pnType, v)) } }
func putList(data *C.pn_data_t, v interface{}) { listValue := reflect.ValueOf(v) C.pn_data_put_list(data) C.pn_data_enter(data) for i := 0; i < listValue.Len(); i++ { marshal(listValue.Index(i).Interface(), data) } C.pn_data_exit(data) }
func putMap(data *C.pn_data_t, v interface{}) { mapValue := reflect.ValueOf(v) C.pn_data_put_map(data) C.pn_data_enter(data) for _, key := range mapValue.MapKeys() { marshal(key.Interface(), data) marshal(mapValue.MapIndex(key).Interface(), data) } C.pn_data_exit(data) }
func getList(data *C.pn_data_t, v interface{}) { pnType := C.pn_data_type(data) if pnType != C.PN_LIST { panic(newUnmarshalError(pnType, v)) } count := int(C.pn_data_get_list(data)) listValue := reflect.MakeSlice(reflect.TypeOf(v).Elem(), count, count) if bool(C.pn_data_enter(data)) { for i := 0; i < count; i++ { if bool(C.pn_data_next(data)) { val := reflect.New(listValue.Type().Elem()) unmarshal(val.Interface(), data) listValue.Index(i).Set(val.Elem()) } } C.pn_data_exit(data) } reflect.ValueOf(v).Elem().Set(listValue) }
func marshal(v interface{}, data *C.pn_data_t) { switch v := v.(type) { case nil: C.pn_data_put_null(data) case bool: C.pn_data_put_bool(data, C.bool(v)) case int8: C.pn_data_put_byte(data, C.int8_t(v)) case int16: C.pn_data_put_short(data, C.int16_t(v)) case int32: C.pn_data_put_int(data, C.int32_t(v)) case int64: C.pn_data_put_long(data, C.int64_t(v)) case int: if unsafe.Sizeof(0) == 8 { C.pn_data_put_long(data, C.int64_t(v)) } else { C.pn_data_put_int(data, C.int32_t(v)) } case uint8: C.pn_data_put_ubyte(data, C.uint8_t(v)) case uint16: C.pn_data_put_ushort(data, C.uint16_t(v)) case uint32: C.pn_data_put_uint(data, C.uint32_t(v)) case uint64: C.pn_data_put_ulong(data, C.uint64_t(v)) case uint: if unsafe.Sizeof(0) == 8 { C.pn_data_put_ulong(data, C.uint64_t(v)) } else { C.pn_data_put_uint(data, C.uint32_t(v)) } case float32: C.pn_data_put_float(data, C.float(v)) case float64: C.pn_data_put_double(data, C.double(v)) case string: C.pn_data_put_string(data, pnBytes([]byte(v))) case []byte: C.pn_data_put_binary(data, pnBytes(v)) case Binary: C.pn_data_put_binary(data, pnBytes([]byte(v))) case Symbol: C.pn_data_put_symbol(data, pnBytes([]byte(v))) case Map: // Special map type C.pn_data_put_map(data) C.pn_data_enter(data) for key, val := range v { marshal(key, data) marshal(val, data) } C.pn_data_exit(data) default: switch reflect.TypeOf(v).Kind() { case reflect.Map: putMap(data, v) case reflect.Slice: putList(data, v) default: panic(fmt.Errorf("cannot marshal %s to AMQP", reflect.TypeOf(v))) } } err := dataError("marshal", data) if err != nil { panic(err) } return }