Remove the context reference from Message struct

The Message struct had a reference to the context which made a few
APIs a little easier.  However it has surprising consequences a long
way down the line as shown in #335: it means any object which has such
a reference needs to keep open a lock if we want to do this refactor
of no longer having a "closed" Context struct on the Rust API (which
has many benefits which will simply that Context struct and is more
the Rust way - RAII etc).

By refactoring away the context reference on the rust API as done in
here however, we push this behaviour of how these references are
handled back to the C-API pointer behaviour: that is unsafe but just
works in a C-like way.  The resulting complexity in the FFI layer is
also notably less than in the #335 alternative.

As a consequence all APIs which require the context, now explicitly
need to get the context passed in as an argument.  It looks like this
is certainly no downside and maybe even beneficial for further API
refactors.

For this strategy to work out the same should be done to
dc_chatlist_t, dc_chat_t and dc_contact_t.  But this working for
dc_msg_t give a reasonable confidence that this is a good approach.
This commit is contained in:
Floris Bruynooghe
2019-09-09 21:35:08 +02:00
committed by Floris Bruynooghe
parent e73671a6ff
commit a0b5e32f98
9 changed files with 206 additions and 223 deletions

View File

@@ -484,11 +484,9 @@ pub unsafe extern "C" fn dc_prepare_msg(
eprintln!("ignoring careless call to dc_prepare_msg()"); eprintln!("ignoring careless call to dc_prepare_msg()");
return 0; return 0;
} }
let context = &mut *context; let context = &mut *context;
let ffi_msg: &mut MessageWrapper = &mut *msg;
let msg = &mut *msg; chat::prepare_msg(context, chat_id, &mut ffi_msg.message)
chat::prepare_msg(context, chat_id, msg)
.unwrap_or_log_default(context, "Failed to prepare message") .unwrap_or_log_default(context, "Failed to prepare message")
} }
@@ -502,11 +500,10 @@ pub unsafe extern "C" fn dc_send_msg(
eprintln!("ignoring careless call to dc_send_msg()"); eprintln!("ignoring careless call to dc_send_msg()");
return 0; return 0;
} }
let context = &mut *context; let context = &mut *context;
let msg = &mut *msg; let ffi_msg = &mut *msg;
chat::send_msg(context, chat_id, &mut ffi_msg.message)
chat::send_msg(context, chat_id, msg).unwrap_or_log_default(context, "Failed to send message") .unwrap_or_log_default(context, "Failed to send message")
} }
#[no_mangle] #[no_mangle]
@@ -537,26 +534,32 @@ pub unsafe extern "C" fn dc_set_draft(
eprintln!("ignoring careless call to dc_set_draft()"); eprintln!("ignoring careless call to dc_set_draft()");
return; return;
} }
let context = &*context; let context = &*context;
let msg = if msg.is_null() { None } else { Some(&mut *msg) }; let msg = if msg.is_null() {
None
} else {
let ffi_msg: &mut MessageWrapper = &mut *msg;
Some(&mut ffi_msg.message)
};
chat::set_draft(context, chat_id, msg) chat::set_draft(context, chat_id, msg)
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_get_draft<'a>( pub unsafe extern "C" fn dc_get_draft(context: *mut dc_context_t, chat_id: u32) -> *mut dc_msg_t {
context: *mut dc_context_t,
chat_id: u32,
) -> *mut dc_msg_t<'a> {
if context.is_null() { if context.is_null() {
eprintln!("ignoring careless call to dc_get_draft()"); eprintln!("ignoring careless call to dc_get_draft()");
return ptr::null_mut(); // NULL explicitly defined as "no draft" return ptr::null_mut(); // NULL explicitly defined as "no draft"
} }
let context = &*context; let context = &*context;
let message = match chat::get_draft(context, chat_id) {
chat::get_draft(context, chat_id).into_raw() Ok(msg) => msg,
Err(e) => {
error!(context, "Failed to get draft for chat #{}: {}", chat_id, e);
return ptr::null_mut();
}
};
let ffi_msg = MessageWrapper { context, message };
Box::into_raw(Box::new(ffi_msg))
} }
#[no_mangle] #[no_mangle]
@@ -1022,18 +1025,21 @@ pub unsafe extern "C" fn dc_star_msgs(
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_get_msg<'a>( pub unsafe extern "C" fn dc_get_msg(context: *mut dc_context_t, msg_id: u32) -> *mut dc_msg_t {
context: *mut dc_context_t,
msg_id: u32,
) -> *mut dc_msg_t<'a> {
if context.is_null() { if context.is_null() {
eprintln!("ignoring careless call to dc_get_msg()"); eprintln!("ignoring careless call to dc_get_msg()");
return ptr::null_mut(); return ptr::null_mut();
} }
let context = &*context; let context = &*context;
let message = match message::dc_get_msg(context, msg_id) {
message::dc_get_msg(context, msg_id).into_raw() Ok(msg) => msg,
Err(e) => {
error!(context, "Error getting msg #{}: {}", msg_id, e);
return ptr::null_mut();
}
};
let ffi_msg = MessageWrapper { context, message };
Box::into_raw(Box::new(ffi_msg))
} }
#[no_mangle] #[no_mangle]
@@ -1865,23 +1871,37 @@ pub unsafe extern "C" fn dc_chat_is_sending_locations(chat: *mut dc_chat_t) -> l
// dc_msg_t // dc_msg_t
#[no_mangle] /// FFI struct for [dc_msg_t]
pub type dc_msg_t<'a> = message::Message<'a>; ///
/// This is the structure behind [dc_msg_t] which is the opaque
/// structure representing a message in the FFI API. It exists
/// because the FFI API has a refernce from the message to the
/// context, but the Rust API does not, so the FFI layer needs to glue
/// these together.
pub struct MessageWrapper {
context: *const dc_context_t,
message: message::Message,
}
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_msg_new<'a>( pub type dc_msg_t = MessageWrapper;
#[no_mangle]
pub unsafe extern "C" fn dc_msg_new(
context: *mut dc_context_t, context: *mut dc_context_t,
viewtype: libc::c_int, viewtype: libc::c_int,
) -> *mut dc_msg_t<'a> { ) -> *mut dc_msg_t {
if context.is_null() { if context.is_null() {
eprintln!("ignoring careless call to dc_msg_new()"); eprintln!("ignoring careless call to dc_msg_new()");
return ptr::null_mut(); return ptr::null_mut();
} }
let context = &*context; let context = &*context;
let viewtype = from_prim(viewtype).expect(&format!("invalid viewtype = {}", viewtype)); let viewtype = from_prim(viewtype).expect(&format!("invalid viewtype = {}", viewtype));
let msg = MessageWrapper {
Box::into_raw(Box::new(message::dc_msg_new(context, viewtype))) context,
message: message::dc_msg_new(viewtype),
};
Box::into_raw(Box::new(msg))
} }
#[no_mangle] #[no_mangle]
@@ -1900,9 +1920,8 @@ pub unsafe extern "C" fn dc_msg_get_id(msg: *mut dc_msg_t) -> u32 {
eprintln!("ignoring careless call to dc_msg_get_id()"); eprintln!("ignoring careless call to dc_msg_get_id()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_id(&ffi_msg.message)
message::dc_msg_get_id(msg)
} }
#[no_mangle] #[no_mangle]
@@ -1911,9 +1930,8 @@ pub unsafe extern "C" fn dc_msg_get_from_id(msg: *mut dc_msg_t) -> u32 {
eprintln!("ignoring careless call to dc_msg_get_from_id()"); eprintln!("ignoring careless call to dc_msg_get_from_id()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_from_id(&ffi_msg.message)
message::dc_msg_get_from_id(msg)
} }
#[no_mangle] #[no_mangle]
@@ -1922,9 +1940,8 @@ pub unsafe extern "C" fn dc_msg_get_chat_id(msg: *mut dc_msg_t) -> u32 {
eprintln!("ignoring careless call to dc_msg_get_chat_id()"); eprintln!("ignoring careless call to dc_msg_get_chat_id()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_chat_id(&ffi_msg.message)
message::dc_msg_get_chat_id(msg)
} }
#[no_mangle] #[no_mangle]
@@ -1933,9 +1950,8 @@ pub unsafe extern "C" fn dc_msg_get_viewtype(msg: *mut dc_msg_t) -> libc::c_int
eprintln!("ignoring careless call to dc_msg_get_viewtype()"); eprintln!("ignoring careless call to dc_msg_get_viewtype()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_viewtype(&ffi_msg.message)
message::dc_msg_get_viewtype(msg)
.to_i64() .to_i64()
.expect("impossible: Viewtype -> i64 conversion failed") as libc::c_int .expect("impossible: Viewtype -> i64 conversion failed") as libc::c_int
} }
@@ -1946,9 +1962,8 @@ pub unsafe extern "C" fn dc_msg_get_state(msg: *mut dc_msg_t) -> libc::c_int {
eprintln!("ignoring careless call to dc_msg_get_state()"); eprintln!("ignoring careless call to dc_msg_get_state()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_state(&ffi_msg.message) as libc::c_int
message::dc_msg_get_state(msg) as libc::c_int
} }
#[no_mangle] #[no_mangle]
@@ -1957,9 +1972,8 @@ pub unsafe extern "C" fn dc_msg_get_timestamp(msg: *mut dc_msg_t) -> i64 {
eprintln!("ignoring careless call to dc_msg_get_received_timestamp()"); eprintln!("ignoring careless call to dc_msg_get_received_timestamp()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_timestamp(&ffi_msg.message)
message::dc_msg_get_timestamp(msg)
} }
#[no_mangle] #[no_mangle]
@@ -1968,9 +1982,8 @@ pub unsafe extern "C" fn dc_msg_get_received_timestamp(msg: *mut dc_msg_t) -> i6
eprintln!("ignoring careless call to dc_msg_get_received_timestamp()"); eprintln!("ignoring careless call to dc_msg_get_received_timestamp()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_received_timestamp(&ffi_msg.message)
message::dc_msg_get_received_timestamp(msg)
} }
#[no_mangle] #[no_mangle]
@@ -1979,9 +1992,8 @@ pub unsafe extern "C" fn dc_msg_get_sort_timestamp(msg: *mut dc_msg_t) -> i64 {
eprintln!("ignoring careless call to dc_msg_get_sort_timestamp()"); eprintln!("ignoring careless call to dc_msg_get_sort_timestamp()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_sort_timestamp(&ffi_msg.message)
message::dc_msg_get_sort_timestamp(msg)
} }
#[no_mangle] #[no_mangle]
@@ -1990,9 +2002,8 @@ pub unsafe extern "C" fn dc_msg_get_text(msg: *mut dc_msg_t) -> *mut libc::c_cha
eprintln!("ignoring careless call to dc_msg_get_text()"); eprintln!("ignoring careless call to dc_msg_get_text()");
return dc_strdup(ptr::null()); return dc_strdup(ptr::null());
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_text(&ffi_msg.message)
message::dc_msg_get_text(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2001,9 +2012,8 @@ pub unsafe extern "C" fn dc_msg_get_file(msg: *mut dc_msg_t) -> *mut libc::c_cha
eprintln!("ignoring careless call to dc_msg_get_file()"); eprintln!("ignoring careless call to dc_msg_get_file()");
return dc_strdup(ptr::null()); return dc_strdup(ptr::null());
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_file(&*ffi_msg.context, &ffi_msg.message)
message::dc_msg_get_file(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2012,9 +2022,8 @@ pub unsafe extern "C" fn dc_msg_get_filename(msg: *mut dc_msg_t) -> *mut libc::c
eprintln!("ignoring careless call to dc_msg_get_filename()"); eprintln!("ignoring careless call to dc_msg_get_filename()");
return dc_strdup(ptr::null()); return dc_strdup(ptr::null());
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_filename(&ffi_msg.message)
message::dc_msg_get_filename(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2023,9 +2032,8 @@ pub unsafe extern "C" fn dc_msg_get_filemime(msg: *mut dc_msg_t) -> *mut libc::c
eprintln!("ignoring careless call to dc_msg_get_filemime()"); eprintln!("ignoring careless call to dc_msg_get_filemime()");
return dc_strdup(ptr::null()); return dc_strdup(ptr::null());
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_filemime(&ffi_msg.message).strdup()
message::dc_msg_get_filemime(msg).strdup()
} }
#[no_mangle] #[no_mangle]
@@ -2034,9 +2042,8 @@ pub unsafe extern "C" fn dc_msg_get_filebytes(msg: *mut dc_msg_t) -> u64 {
eprintln!("ignoring careless call to dc_msg_get_filebytes()"); eprintln!("ignoring careless call to dc_msg_get_filebytes()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_filebytes(&*ffi_msg.context, &ffi_msg.message)
message::dc_msg_get_filebytes(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2045,9 +2052,8 @@ pub unsafe extern "C" fn dc_msg_get_width(msg: *mut dc_msg_t) -> libc::c_int {
eprintln!("ignoring careless call to dc_msg_get_width()"); eprintln!("ignoring careless call to dc_msg_get_width()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_width(&ffi_msg.message)
message::dc_msg_get_width(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2056,9 +2062,8 @@ pub unsafe extern "C" fn dc_msg_get_height(msg: *mut dc_msg_t) -> libc::c_int {
eprintln!("ignoring careless call to dc_msg_get_height()"); eprintln!("ignoring careless call to dc_msg_get_height()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_height(&ffi_msg.message)
message::dc_msg_get_height(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2067,9 +2072,8 @@ pub unsafe extern "C" fn dc_msg_get_duration(msg: *mut dc_msg_t) -> libc::c_int
eprintln!("ignoring careless call to dc_msg_get_duration()"); eprintln!("ignoring careless call to dc_msg_get_duration()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_duration(&ffi_msg.message)
message::dc_msg_get_duration(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2078,25 +2082,22 @@ pub unsafe extern "C" fn dc_msg_get_showpadlock(msg: *mut dc_msg_t) -> libc::c_i
eprintln!("ignoring careless call to dc_msg_get_showpadlock()"); eprintln!("ignoring careless call to dc_msg_get_showpadlock()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_showpadlock(&ffi_msg.message)
message::dc_msg_get_showpadlock(msg)
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_msg_get_summary<'a>( pub unsafe extern "C" fn dc_msg_get_summary(
msg: *mut dc_msg_t<'a>, msg: *mut dc_msg_t,
chat: *mut dc_chat_t<'a>, chat: *mut dc_chat_t,
) -> *mut dc_lot_t { ) -> *mut dc_lot_t {
if msg.is_null() { if msg.is_null() {
eprintln!("ignoring careless call to dc_msg_get_summary()"); eprintln!("ignoring careless call to dc_msg_get_summary()");
return ptr::null_mut(); return ptr::null_mut();
} }
let chat = if chat.is_null() { None } else { Some(&*chat) }; let chat = if chat.is_null() { None } else { Some(&*chat) };
let ffi_msg = &mut *msg;
let msg = &mut *msg; let lot = message::dc_msg_get_summary(&*ffi_msg.context, &mut ffi_msg.message, chat);
let lot = message::dc_msg_get_summary(msg, chat);
Box::into_raw(Box::new(lot)) Box::into_raw(Box::new(lot))
} }
@@ -2109,9 +2110,12 @@ pub unsafe extern "C" fn dc_msg_get_summarytext(
eprintln!("ignoring careless call to dc_msg_get_summarytext()"); eprintln!("ignoring careless call to dc_msg_get_summarytext()");
return dc_strdup(ptr::null()); return dc_strdup(ptr::null());
} }
let ffi_msg = &mut *msg;
let msg = &mut *msg; message::dc_msg_get_summarytext(
message::dc_msg_get_summarytext(msg, approx_characters.try_into().unwrap()) &*ffi_msg.context,
&mut ffi_msg.message,
approx_characters.try_into().unwrap(),
)
} }
#[no_mangle] #[no_mangle]
@@ -2120,9 +2124,8 @@ pub unsafe extern "C" fn dc_msg_has_deviating_timestamp(msg: *mut dc_msg_t) -> l
eprintln!("ignoring careless call to dc_msg_has_deviating_timestamp()"); eprintln!("ignoring careless call to dc_msg_has_deviating_timestamp()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_has_deviating_timestamp(&ffi_msg.message)
message::dc_msg_has_deviating_timestamp(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2131,9 +2134,8 @@ pub unsafe extern "C" fn dc_msg_has_location(msg: *mut dc_msg_t) -> libc::c_int
eprintln!("ignoring careless call to dc_msg_has_location()"); eprintln!("ignoring careless call to dc_msg_has_location()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_has_location(&ffi_msg.message) as libc::c_int
message::dc_msg_has_location(msg) as libc::c_int
} }
#[no_mangle] #[no_mangle]
@@ -2142,9 +2144,8 @@ pub unsafe extern "C" fn dc_msg_is_sent(msg: *mut dc_msg_t) -> libc::c_int {
eprintln!("ignoring careless call to dc_msg_is_sent()"); eprintln!("ignoring careless call to dc_msg_is_sent()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_is_sent(&ffi_msg.message)
message::dc_msg_is_sent(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2153,9 +2154,8 @@ pub unsafe extern "C" fn dc_msg_is_starred(msg: *mut dc_msg_t) -> libc::c_int {
eprintln!("ignoring careless call to dc_msg_is_starred()"); eprintln!("ignoring careless call to dc_msg_is_starred()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_is_starred(&ffi_msg.message).into()
message::dc_msg_is_starred(msg).into()
} }
#[no_mangle] #[no_mangle]
@@ -2164,9 +2164,8 @@ pub unsafe extern "C" fn dc_msg_is_forwarded(msg: *mut dc_msg_t) -> libc::c_int
eprintln!("ignoring careless call to dc_msg_is_forwarded()"); eprintln!("ignoring careless call to dc_msg_is_forwarded()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_is_forwarded(&ffi_msg.message)
message::dc_msg_is_forwarded(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2175,9 +2174,8 @@ pub unsafe extern "C" fn dc_msg_is_info(msg: *mut dc_msg_t) -> libc::c_int {
eprintln!("ignoring careless call to dc_msg_is_info()"); eprintln!("ignoring careless call to dc_msg_is_info()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_is_info(&ffi_msg.message)
message::dc_msg_is_info(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2186,9 +2184,8 @@ pub unsafe extern "C" fn dc_msg_is_increation(msg: *mut dc_msg_t) -> libc::c_int
eprintln!("ignoring careless call to dc_msg_is_increation()"); eprintln!("ignoring careless call to dc_msg_is_increation()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_is_increation(&ffi_msg.message)
message::dc_msg_is_increation(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2197,9 +2194,8 @@ pub unsafe extern "C" fn dc_msg_is_setupmessage(msg: *mut dc_msg_t) -> libc::c_i
eprintln!("ignoring careless call to dc_msg_is_setupmessage()"); eprintln!("ignoring careless call to dc_msg_is_setupmessage()");
return 0; return 0;
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_is_setupmessage(&ffi_msg.message) as libc::c_int
message::dc_msg_is_setupmessage(msg) as libc::c_int
} }
#[no_mangle] #[no_mangle]
@@ -2208,9 +2204,8 @@ pub unsafe extern "C" fn dc_msg_get_setupcodebegin(msg: *mut dc_msg_t) -> *mut l
eprintln!("ignoring careless call to dc_msg_get_setupcodebegin()"); eprintln!("ignoring careless call to dc_msg_get_setupcodebegin()");
return dc_strdup(ptr::null()); return dc_strdup(ptr::null());
} }
let ffi_msg = &*msg;
let msg = &*msg; message::dc_msg_get_setupcodebegin(&*ffi_msg.context, &ffi_msg.message)
message::dc_msg_get_setupcodebegin(msg)
} }
#[no_mangle] #[no_mangle]
@@ -2219,10 +2214,9 @@ pub unsafe extern "C" fn dc_msg_set_text(msg: *mut dc_msg_t, text: *mut libc::c_
eprintln!("ignoring careless call to dc_msg_set_text()"); eprintln!("ignoring careless call to dc_msg_set_text()");
return; return;
} }
let ffi_msg = &mut *msg;
let msg = &mut *msg;
// TODO: {text} equal to NULL is treated as "", which is strange. Does anyone rely on it? // TODO: {text} equal to NULL is treated as "", which is strange. Does anyone rely on it?
message::dc_msg_set_text(msg, text) message::dc_msg_set_text(&mut ffi_msg.message, text)
} }
#[no_mangle] #[no_mangle]
@@ -2235,9 +2229,8 @@ pub unsafe extern "C" fn dc_msg_set_file(
eprintln!("ignoring careless call to dc_msg_set_file()"); eprintln!("ignoring careless call to dc_msg_set_file()");
return; return;
} }
let ffi_msg = &mut *msg;
let msg = &mut *msg; message::dc_msg_set_file(&mut ffi_msg.message, file, filemime)
message::dc_msg_set_file(msg, file, filemime)
} }
#[no_mangle] #[no_mangle]
@@ -2250,9 +2243,8 @@ pub unsafe extern "C" fn dc_msg_set_dimension(
eprintln!("ignoring careless call to dc_msg_set_dimension()"); eprintln!("ignoring careless call to dc_msg_set_dimension()");
return; return;
} }
let ffi_msg = &mut *msg;
let msg = &mut *msg; message::dc_msg_set_dimension(&mut ffi_msg.message, width, height)
message::dc_msg_set_dimension(msg, width, height)
} }
#[no_mangle] #[no_mangle]
@@ -2261,9 +2253,8 @@ pub unsafe extern "C" fn dc_msg_set_duration(msg: *mut dc_msg_t, duration: libc:
eprintln!("ignoring careless call to dc_msg_set_duration()"); eprintln!("ignoring careless call to dc_msg_set_duration()");
return; return;
} }
let ffi_msg = &mut *msg;
let msg = &mut *msg; message::dc_msg_set_duration(&mut ffi_msg.message, duration)
message::dc_msg_set_duration(msg, duration)
} }
#[no_mangle] #[no_mangle]
@@ -2276,9 +2267,8 @@ pub unsafe extern "C" fn dc_msg_set_location(
eprintln!("ignoring careless call to dc_msg_set_location()"); eprintln!("ignoring careless call to dc_msg_set_location()");
return; return;
} }
let ffi_msg = &mut *msg;
let msg = &mut *msg; message::dc_msg_set_location(&mut ffi_msg.message, latitude, longitude)
message::dc_msg_set_location(msg, latitude, longitude)
} }
#[no_mangle] #[no_mangle]
@@ -2292,9 +2282,14 @@ pub unsafe extern "C" fn dc_msg_latefiling_mediasize(
eprintln!("ignoring careless call to dc_msg_latefiling_mediasize()"); eprintln!("ignoring careless call to dc_msg_latefiling_mediasize()");
return; return;
} }
let ffi_msg = &mut *msg;
let msg = &mut *msg; message::dc_msg_latefiling_mediasize(
message::dc_msg_latefiling_mediasize(msg, width, height, duration) &*ffi_msg.context,
&mut ffi_msg.message,
width,
height,
duration,
)
} }
// dc_contact_t // dc_contact_t

View File

@@ -476,7 +476,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
let msg_id: u32 = arg1.parse()?; let msg_id: u32 = arg1.parse()?;
let msg = dc_get_msg(context, msg_id)?; let msg = dc_get_msg(context, msg_id)?;
if dc_msg_is_setupmessage(&msg) { if dc_msg_is_setupmessage(&msg) {
let setupcodebegin = dc_msg_get_setupcodebegin(&msg); let setupcodebegin = dc_msg_get_setupcodebegin(context, &msg);
println!( println!(
"The setup code for setup message Msg#{} starts with: {}", "The setup code for setup message Msg#{} starts with: {}",
msg_id, msg_id,
@@ -836,14 +836,11 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
ensure!(sel_chat.is_some(), "No chat selected."); ensure!(sel_chat.is_some(), "No chat selected.");
ensure!(!arg1.is_empty(), "No file given."); ensure!(!arg1.is_empty(), "No file given.");
let mut msg = dc_msg_new( let mut msg = dc_msg_new(if arg0 == "sendimage" {
context, Viewtype::Image
if arg0 == "sendimage" { } else {
Viewtype::Image Viewtype::File
} else { });
Viewtype::File
},
);
dc_msg_set_file(&mut msg, arg1_c, ptr::null()); dc_msg_set_file(&mut msg, arg1_c, ptr::null());
if !arg2.is_empty() { if !arg2.is_empty() {
dc_msg_set_text(&mut msg, arg2_c); dc_msg_set_text(&mut msg, arg2_c);
@@ -868,7 +865,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
ensure!(sel_chat.is_some(), "No chat selected."); ensure!(sel_chat.is_some(), "No chat selected.");
if !arg1.is_empty() { if !arg1.is_empty() {
let mut draft = dc_msg_new(context, Viewtype::Text); let mut draft = dc_msg_new(Viewtype::Text);
dc_msg_set_text(&mut draft, arg1_c); dc_msg_set_text(&mut draft, arg1_c);
chat::set_draft( chat::set_draft(
context, context,

View File

@@ -635,7 +635,7 @@ pub fn get_by_contact_id(context: &Context, contact_id: u32) -> Result<u32, Erro
pub fn prepare_msg<'a>( pub fn prepare_msg<'a>(
context: &'a Context, context: &'a Context,
chat_id: u32, chat_id: u32,
msg: &mut Message<'a>, msg: &mut Message,
) -> Result<u32, Error> { ) -> Result<u32, Error> {
ensure!( ensure!(
chat_id > DC_CHAT_ID_LAST_SPECIAL, chat_id > DC_CHAT_ID_LAST_SPECIAL,
@@ -665,13 +665,8 @@ pub fn msgtype_has_file(msgtype: Viewtype) -> bool {
} }
} }
fn prepare_msg_common<'a>( fn prepare_msg_common(context: &Context, chat_id: u32, msg: &mut Message) -> Result<u32, Error> {
context: &'a Context,
chat_id: u32,
msg: &mut Message<'a>,
) -> Result<u32, Error> {
msg.id = 0; msg.id = 0;
msg.context = context;
if msg.type_0 == Viewtype::Text { if msg.type_0 == Viewtype::Text {
// the caller should check if the message text is empty // the caller should check if the message text is empty
@@ -787,11 +782,7 @@ pub fn unarchive(context: &Context, chat_id: u32) -> Result<(), Error> {
/// However, this does not imply, the message really reached the recipient - /// However, this does not imply, the message really reached the recipient -
/// sending may be delayed eg. due to network problems. However, from your /// sending may be delayed eg. due to network problems. However, from your
/// view, you're done with the message. Sooner or later it will find its way. /// view, you're done with the message. Sooner or later it will find its way.
pub fn send_msg<'a>( pub fn send_msg(context: &Context, chat_id: u32, msg: &mut Message) -> Result<u32, Error> {
context: &'a Context,
chat_id: u32,
msg: &mut Message<'a>,
) -> Result<u32, Error> {
if msg.state != MessageState::OutPreparing { if msg.state != MessageState::OutPreparing {
// automatically prepare normal messages // automatically prepare normal messages
prepare_msg_common(context, chat_id, msg)?; prepare_msg_common(context, chat_id, msg)?;
@@ -835,7 +826,7 @@ pub fn send_msg<'a>(
} }
} }
msg.param.remove(Param::PrepForwards); msg.param.remove(Param::PrepForwards);
dc_msg_save_param_to_disk(msg); dc_msg_save_param_to_disk(context, msg);
} }
} }
@@ -853,7 +844,7 @@ pub unsafe fn send_text_msg(
chat_id chat_id
); );
let mut msg = dc_msg_new(context, Viewtype::Text); let mut msg = dc_msg_new(Viewtype::Text);
msg.text = Some(text_to_send); msg.text = Some(text_to_send);
send_msg(context, chat_id, &mut msg) send_msg(context, chat_id, &mut msg)
} }
@@ -1295,7 +1286,7 @@ pub unsafe fn create_group_chat(
if chat_id != 0 { if chat_id != 0 {
if 0 != add_to_chat_contacts_table(context, chat_id, 1) { if 0 != add_to_chat_contacts_table(context, chat_id, 1) {
let mut draft_msg = dc_msg_new(context, Viewtype::Text); let mut draft_msg = dc_msg_new(Viewtype::Text);
dc_msg_set_text(&mut draft_msg, draft_txt.as_ptr()); dc_msg_set_text(&mut draft_msg, draft_txt.as_ptr());
set_draft_raw(context, chat_id, Some(&mut draft_msg)); set_draft_raw(context, chat_id, Some(&mut draft_msg));
} }
@@ -1340,7 +1331,7 @@ pub fn add_contact_to_chat_ex(
if contact.is_err() || chat_id <= DC_CHAT_ID_LAST_SPECIAL { if contact.is_err() || chat_id <= DC_CHAT_ID_LAST_SPECIAL {
return 0; return 0;
} }
let mut msg = unsafe { dc_msg_new_untyped(context) }; let mut msg = dc_msg_new_untyped();
reset_gossiped_timestamp(context, chat_id); reset_gossiped_timestamp(context, chat_id);
let contact = contact.unwrap(); let contact = contact.unwrap();
@@ -1489,7 +1480,7 @@ pub unsafe fn remove_contact_from_chat(
"Cannot remove special contact" "Cannot remove special contact"
); );
let mut msg = dc_msg_new_untyped(context); let mut msg = dc_msg_new_untyped();
let mut success = false; let mut success = false;
/* we do not check if "contact_id" exists but just delete all records with the id from chats_contacts */ /* we do not check if "contact_id" exists but just delete all records with the id from chats_contacts */
@@ -1588,7 +1579,7 @@ pub unsafe fn set_chat_name(
ensure!(chat_id > DC_CHAT_ID_LAST_SPECIAL, "Invalid chat ID"); ensure!(chat_id > DC_CHAT_ID_LAST_SPECIAL, "Invalid chat ID");
let chat = Chat::load_from_db(context, chat_id)?; let chat = Chat::load_from_db(context, chat_id)?;
let mut msg = dc_msg_new_untyped(context); let mut msg = dc_msg_new_untyped();
if real_group_exists(context, chat_id) { if real_group_exists(context, chat_id) {
if &chat.name == new_name.as_ref() { if &chat.name == new_name.as_ref() {
@@ -1684,7 +1675,7 @@ pub fn set_chat_profile_image(
chat.param.set(Param::ProfileImage, &new_image_rel); chat.param.set(Param::ProfileImage, &new_image_rel);
if chat.update_param().is_ok() { if chat.update_param().is_ok() {
if chat.is_promoted() { if chat.is_promoted() {
let mut msg = unsafe { dc_msg_new_untyped(context) }; let mut msg = dc_msg_new_untyped();
msg.param.set_int(Param::Cmd, DC_CMD_GROUPIMAGE_CHANGED); msg.param.set_int(Param::Cmd, DC_CMD_GROUPIMAGE_CHANGED);
msg.type_0 = Viewtype::Text; msg.type_0 = Viewtype::Text;
msg.text = Some(context.stock_system_msg( msg.text = Some(context.stock_system_msg(
@@ -1779,7 +1770,7 @@ pub unsafe fn forward_msgs(
msg.param.set(Param::PrepForwards, new_msg_id.to_string()); msg.param.set(Param::PrepForwards, new_msg_id.to_string());
} }
dc_msg_save_param_to_disk(&mut msg); dc_msg_save_param_to_disk(context, &mut msg);
msg.param = save_param; msg.param = save_param;
} else { } else {
msg.state = MessageState::OutPending; msg.state = MessageState::OutPending;

View File

@@ -138,7 +138,7 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char {
)) ))
{ {
if let Ok(chat_id) = chat::create_by_contact_id(context, 1) { if let Ok(chat_id) = chat::create_by_contact_id(context, 1) {
msg = dc_msg_new_untyped(context); msg = dc_msg_new_untyped();
msg.type_0 = Viewtype::File; msg.type_0 = Viewtype::File;
msg.param.set(Param::File, as_str(setup_file_name)); msg.param.set(Param::File, as_str(setup_file_name));
@@ -281,7 +281,7 @@ pub unsafe fn dc_continue_key_transfer(
if msg.is_err() if msg.is_err()
|| !dc_msg_is_setupmessage(msg.as_ref().unwrap()) || !dc_msg_is_setupmessage(msg.as_ref().unwrap())
|| { || {
filename = dc_msg_get_file(msg.as_ref().unwrap()); filename = dc_msg_get_file(context, msg.as_ref().unwrap());
filename.is_null() filename.is_null()
} }
|| *filename.offset(0isize) as libc::c_int == 0i32 || *filename.offset(0isize) as libc::c_int == 0i32

View File

@@ -37,7 +37,7 @@ pub struct dc_mimefactory_t<'a> {
pub timestamp: i64, pub timestamp: i64,
pub rfc724_mid: *mut libc::c_char, pub rfc724_mid: *mut libc::c_char,
pub loaded: dc_mimefactory_loaded_t, pub loaded: dc_mimefactory_loaded_t,
pub msg: Message<'a>, pub msg: Message,
pub chat: Option<Chat<'a>>, pub chat: Option<Chat<'a>>,
pub increation: libc::c_int, pub increation: libc::c_int,
pub in_reply_to: *mut libc::c_char, pub in_reply_to: *mut libc::c_char,
@@ -335,7 +335,10 @@ pub unsafe fn dc_mimefactory_load_mdn<'a>(
} }
// TODO should return bool /rtn // TODO should return bool /rtn
pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_int { pub unsafe fn dc_mimefactory_render(
context: &Context,
factory: &mut dc_mimefactory_t,
) -> libc::c_int {
let subject: *mut mailimf_subject; let subject: *mut mailimf_subject;
let mut ok_to_continue = true; let mut ok_to_continue = true;
let imf_fields: *mut mailimf_fields; let imf_fields: *mut mailimf_fields;
@@ -586,7 +589,7 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
} }
if 0 != msg.param.get_int(Param::Arg2).unwrap_or_default() & 0x1 { if 0 != msg.param.get_int(Param::Arg2).unwrap_or_default() & 0x1 {
info!( info!(
msg.context, context,
"sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>",
"vg-member-added", "vg-member-added",
); );
@@ -654,7 +657,7 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
let step = msg.param.get(Param::Arg).unwrap_or_default().strdup(); let step = msg.param.get(Param::Arg).unwrap_or_default().strdup();
if strlen(step) > 0 { if strlen(step) > 0 {
info!( info!(
msg.context, context,
"sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>",
as_str(step), as_str(step),
); );
@@ -725,12 +728,13 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
} }
if let Some(grpimage) = grpimage { if let Some(grpimage) = grpimage {
info!(factory.context, "setting group image '{}'", grpimage); info!(factory.context, "setting group image '{}'", grpimage);
let mut meta = dc_msg_new_untyped(factory.context); let mut meta = dc_msg_new_untyped();
meta.type_0 = Viewtype::Image; meta.type_0 = Viewtype::Image;
meta.param.set(Param::File, grpimage); meta.param.set(Param::File, grpimage);
let mut filename_as_sent = ptr::null_mut(); let mut filename_as_sent = ptr::null_mut();
meta_part = build_body_file( meta_part = build_body_file(
context,
&meta, &meta,
b"group-image\x00" as *const u8 as *const libc::c_char, b"group-image\x00" as *const u8 as *const libc::c_char,
&mut filename_as_sent, &mut filename_as_sent,
@@ -833,7 +837,7 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
/* add attachment part */ /* add attachment part */
if chat::msgtype_has_file(factory.msg.type_0) { if chat::msgtype_has_file(factory.msg.type_0) {
if !is_file_size_okay(&factory.msg) { if !is_file_size_okay(context, &factory.msg) {
let error: *mut libc::c_char = dc_mprintf( let error: *mut libc::c_char = dc_mprintf(
b"Message exceeds the recommended %i MB.\x00" as *const u8 b"Message exceeds the recommended %i MB.\x00" as *const u8
as *const libc::c_char, as *const libc::c_char,
@@ -844,7 +848,7 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
ok_to_continue = false; ok_to_continue = false;
} else { } else {
let file_part: *mut mailmime = let file_part: *mut mailmime =
build_body_file(&factory.msg, ptr::null(), ptr::null_mut()); build_body_file(context, &factory.msg, ptr::null(), ptr::null_mut());
if !file_part.is_null() { if !file_part.is_null() {
mailmime_smart_add_part(message, file_part); mailmime_smart_add_part(message, file_part);
parts += 1 parts += 1
@@ -892,12 +896,9 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
mailmime_smart_add_part(message, kml_mime_part); mailmime_smart_add_part(message, kml_mime_part);
} }
if location::is_sending_locations_to_chat( if location::is_sending_locations_to_chat(context, factory.msg.chat_id) {
factory.msg.context,
factory.msg.chat_id,
) {
if let Ok((kml_file, last_added_location_id)) = if let Ok((kml_file, last_added_location_id)) =
location::get_kml(factory.msg.context, factory.msg.chat_id) location::get_kml(context, factory.msg.chat_id)
{ {
let content_type = mailmime_content_new_with_str( let content_type = mailmime_content_new_with_str(
b"application/vnd.google-earth.kml+xml\x00" as *const u8 b"application/vnd.google-earth.kml+xml\x00" as *const u8
@@ -950,7 +951,7 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
.stock_str(StockMessage::EncryptedMsg) .stock_str(StockMessage::EncryptedMsg)
.into_owned() .into_owned()
} else { } else {
to_string(dc_msg_get_summarytext(&mut factory.msg, 32)) to_string(dc_msg_get_summarytext(context, &mut factory.msg, 32))
}; };
let p2 = factory let p2 = factory
.context .context
@@ -1134,6 +1135,7 @@ unsafe fn build_body_text(text: *mut libc::c_char) -> *mut mailmime {
#[allow(non_snake_case)] #[allow(non_snake_case)]
unsafe fn build_body_file( unsafe fn build_body_file(
context: &Context,
msg: &Message, msg: &Message,
mut base_name: *const libc::c_char, mut base_name: *const libc::c_char,
ret_file_name_as_sent: *mut *mut libc::c_char, ret_file_name_as_sent: *mut *mut libc::c_char,
@@ -1286,7 +1288,7 @@ unsafe fn build_body_file(
) as *mut libc::c_void, ) as *mut libc::c_void,
); );
mime_sub = mailmime_new_empty(content, mime_fields); mime_sub = mailmime_new_empty(content, mime_fields);
mailmime_set_body_file(mime_sub, dc_get_abs_path(msg.context, path_filename)); mailmime_set_body_file(mime_sub, dc_get_abs_path(context, path_filename));
if !ret_file_name_as_sent.is_null() { if !ret_file_name_as_sent.is_null() {
*ret_file_name_as_sent = dc_strdup(filename_to_send) *ret_file_name_as_sent = dc_strdup(filename_to_send)
} }
@@ -1303,10 +1305,10 @@ unsafe fn build_body_file(
/******************************************************************************* /*******************************************************************************
* Render * Render
******************************************************************************/ ******************************************************************************/
unsafe fn is_file_size_okay(msg: &Message) -> bool { unsafe fn is_file_size_okay(context: &Context, msg: &Message) -> bool {
let mut file_size_okay = true; let mut file_size_okay = true;
let path = msg.param.get(Param::File).unwrap_or_default(); let path = msg.param.get(Param::File).unwrap_or_default();
let bytes = dc_get_filebytes(msg.context, &path); let bytes = dc_get_filebytes(context, &path);
if bytes > (49 * 1024 * 1024 / 4 * 3) { if bytes > (49 * 1024 * 1024 / 4 * 3) {
file_size_okay = false; file_size_okay = false;

View File

@@ -677,12 +677,12 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_int {
mimefactory.msg.param.set_int(Param::Height, height as i32); mimefactory.msg.param.set_int(Param::Height, height as i32);
} }
} }
dc_msg_save_param_to_disk(&mut mimefactory.msg); dc_msg_save_param_to_disk(context, &mut mimefactory.msg);
} }
} }
} }
/* create message */ /* create message */
if 0 == dc_mimefactory_render(&mut mimefactory) { if 0 == dc_mimefactory_render(context, &mut mimefactory) {
dc_set_msg_failed(context, msg_id, as_opt_str(mimefactory.error)); dc_set_msg_failed(context, msg_id, as_opt_str(mimefactory.error));
} else if 0 } else if 0
!= mimefactory != mimefactory
@@ -745,7 +745,7 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_int {
== 0 == 0
{ {
mimefactory.msg.param.set_int(Param::GuranteeE2ee, 1); mimefactory.msg.param.set_int(Param::GuranteeE2ee, 1);
dc_msg_save_param_to_disk(&mut mimefactory.msg); dc_msg_save_param_to_disk(context, &mut mimefactory.msg);
} }
success = add_smtp_job(context, Action::SendMsgToSmtp, &mut mimefactory); success = add_smtp_job(context, Action::SendMsgToSmtp, &mut mimefactory);
} }
@@ -992,7 +992,7 @@ fn connect_to_inbox(context: &Context, inbox: &Imap) -> libc::c_int {
fn send_mdn(context: &Context, msg_id: uint32_t) { fn send_mdn(context: &Context, msg_id: uint32_t) {
if let Ok(mut mimefactory) = unsafe { dc_mimefactory_load_mdn(context, msg_id) } { if let Ok(mut mimefactory) = unsafe { dc_mimefactory_load_mdn(context, msg_id) } {
if 0 != unsafe { dc_mimefactory_render(&mut mimefactory) } { if 0 != unsafe { dc_mimefactory_render(context, &mut mimefactory) } {
add_smtp_job(context, Action::SendMdn, &mut mimefactory); add_smtp_job(context, Action::SendMdn, &mut mimefactory);
} }
} }

View File

@@ -215,7 +215,7 @@ pub fn send_locations_to_chat(context: &Context, chat_id: u32, seconds: i64) {
.is_ok() .is_ok()
{ {
if 0 != seconds && !is_sending_locations_before { if 0 != seconds && !is_sending_locations_before {
msg = dc_msg_new(context, Viewtype::Text); msg = dc_msg_new(Viewtype::Text);
msg.text = msg.text =
Some(context.stock_system_msg(StockMessage::MsgLocationEnabled, "", "", 0)); Some(context.stock_system_msg(StockMessage::MsgLocationEnabled, "", "", 0));
msg.param.set_int(Param::Cmd, 8); msg.param.set_int(Param::Cmd, 8);
@@ -606,7 +606,7 @@ pub fn job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: &Job) {
// the easiest way to determine this, is to check for an empty message queue. // the easiest way to determine this, is to check for an empty message queue.
// (might not be 100%, however, as positions are sent combined later // (might not be 100%, however, as positions are sent combined later
// and dc_set_location() is typically called periodically, this is ok) // and dc_set_location() is typically called periodically, this is ok)
let mut msg = dc_msg_new(context, Viewtype::Text); let mut msg = dc_msg_new(Viewtype::Text);
msg.hidden = true; msg.hidden = true;
msg.param.set_int(Param::Cmd, 9); msg.param.set_int(Param::Cmd, 9);
Some((chat_id, msg)) Some((chat_id, msg))

View File

@@ -137,7 +137,7 @@ impl Lot {
/// approx. max. length returned by dc_msg_get_text() /// approx. max. length returned by dc_msg_get_text()
/// approx. max. length returned by dc_get_msg_info() /// approx. max. length returned by dc_get_msg_info()
#[derive(Clone)] #[derive(Clone)]
pub struct Message<'a> { pub struct Message {
pub id: u32, pub id: u32,
pub from_id: u32, pub from_id: u32,
pub to_id: u32, pub to_id: u32,
@@ -150,7 +150,6 @@ pub struct Message<'a> {
pub timestamp_sent: i64, pub timestamp_sent: i64,
pub timestamp_rcvd: i64, pub timestamp_rcvd: i64,
pub text: Option<String>, pub text: Option<String>,
pub context: &'a Context,
pub rfc724_mid: *mut libc::c_char, pub rfc724_mid: *mut libc::c_char,
pub in_reply_to: *mut libc::c_char, pub in_reply_to: *mut libc::c_char,
pub server_folder: Option<String>, pub server_folder: Option<String>,
@@ -270,7 +269,7 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
_ => {} _ => {}
} }
let p = dc_msg_get_file(&msg); let p = dc_msg_get_file(context, &msg);
if !p.is_null() && 0 != *p.offset(0isize) as libc::c_int { if !p.is_null() && 0 != *p.offset(0isize) as libc::c_int {
ret += &format!( ret += &format!(
"\nFile: {}, {}, bytes\n", "\nFile: {}, {}, bytes\n",
@@ -310,11 +309,11 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
ret.strdup() ret.strdup()
} }
pub unsafe fn dc_msg_new_untyped<'a>(context: &'a Context) -> Message<'a> { pub fn dc_msg_new_untyped() -> Message {
dc_msg_new(context, Viewtype::Unknown) dc_msg_new(Viewtype::Unknown)
} }
pub fn dc_msg_new<'a>(context: &'a Context, viewtype: Viewtype) -> Message<'a> { pub fn dc_msg_new(viewtype: Viewtype) -> Message {
Message { Message {
id: 0, id: 0,
from_id: 0, from_id: 0,
@@ -328,7 +327,6 @@ pub fn dc_msg_new<'a>(context: &'a Context, viewtype: Viewtype) -> Message<'a> {
timestamp_sent: 0, timestamp_sent: 0,
timestamp_rcvd: 0, timestamp_rcvd: 0,
text: None, text: None,
context,
rfc724_mid: std::ptr::null_mut(), rfc724_mid: std::ptr::null_mut(),
in_reply_to: std::ptr::null_mut(), in_reply_to: std::ptr::null_mut(),
server_folder: None, server_folder: None,
@@ -341,7 +339,7 @@ pub fn dc_msg_new<'a>(context: &'a Context, viewtype: Viewtype) -> Message<'a> {
} }
} }
impl<'a> Drop for Message<'a> { impl Drop for Message {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
free(self.rfc724_mid.cast()); free(self.rfc724_mid.cast());
@@ -380,11 +378,11 @@ pub fn dc_msg_guess_msgtype_from_suffix(path: &Path) -> Option<(Viewtype, &str)>
KNOWN.get(extension).map(|x| *x) KNOWN.get(extension).map(|x| *x)
} }
pub unsafe fn dc_msg_get_file(msg: &Message) -> *mut libc::c_char { pub unsafe fn dc_msg_get_file(context: &Context, msg: &Message) -> *mut libc::c_char {
let mut file_abs = ptr::null_mut(); let mut file_abs = ptr::null_mut();
if let Some(file_rel) = msg.param.get(Param::File) { if let Some(file_rel) = msg.param.get(Param::File) {
file_abs = dc_get_abs_path(msg.context, file_rel); file_abs = dc_get_abs_path(context, file_rel);
} }
if !file_abs.is_null() { if !file_abs.is_null() {
file_abs file_abs
@@ -440,7 +438,7 @@ pub fn dc_msg_get_timestamp(msg: &Message) -> i64 {
} }
} }
pub fn dc_msg_load_from_db<'a>(context: &'a Context, id: u32) -> Result<Message<'a>, Error> { pub fn dc_msg_load_from_db(context: &Context, id: u32) -> Result<Message, Error> {
context.sql.query_row( context.sql.query_row(
"SELECT \ "SELECT \
m.id,rfc724_mid,m.mime_in_reply_to,m.server_folder,m.server_uid,m.move_state,m.chat_id, \ m.id,rfc724_mid,m.mime_in_reply_to,m.server_folder,m.server_uid,m.move_state,m.chat_id, \
@@ -451,8 +449,7 @@ pub fn dc_msg_load_from_db<'a>(context: &'a Context, id: u32) -> Result<Message<
params![id as i32], params![id as i32],
|row| { |row| {
unsafe { unsafe {
let mut msg = dc_msg_new_untyped(context); let mut msg = dc_msg_new_untyped();
msg.context = context;
msg.id = row.get::<_, i32>(0)? as u32; msg.id = row.get::<_, i32>(0)? as u32;
msg.rfc724_mid = row.get::<_, String>(1)?.strdup(); msg.rfc724_mid = row.get::<_, String>(1)?.strdup();
msg.in_reply_to = match row.get::<_, Option<String>>(2)? { msg.in_reply_to = match row.get::<_, Option<String>>(2)? {
@@ -643,7 +640,7 @@ pub fn dc_star_msgs(
.is_ok() .is_ok()
} }
pub fn dc_get_msg<'a>(context: &'a Context, msg_id: u32) -> Result<Message<'a>, Error> { pub fn dc_get_msg(context: &Context, msg_id: u32) -> Result<Message, Error> {
dc_msg_load_from_db(context, msg_id) dc_msg_load_from_db(context, msg_id)
} }
@@ -701,11 +698,10 @@ pub unsafe fn dc_msg_get_filename(msg: &Message) -> *mut libc::c_char {
} }
} }
pub unsafe fn dc_msg_get_filebytes(msg: &Message) -> uint64_t { pub fn dc_msg_get_filebytes(context: &Context, msg: &Message) -> uint64_t {
if let Some(file) = msg.param.get(Param::File) { if let Some(file) = msg.param.get(Param::File) {
return dc_get_filebytes(msg.context, &file); return dc_get_filebytes(context, &file);
} }
0 0
} }
@@ -730,14 +726,14 @@ pub fn dc_msg_get_showpadlock(msg: &Message) -> libc::c_int {
0 0
} }
pub unsafe fn dc_msg_get_summary<'a>(msg: &mut Message<'a>, chat: Option<&Chat<'a>>) -> Lot { pub fn dc_msg_get_summary(context: &Context, msg: &mut Message, chat: Option<&Chat>) -> Lot {
let mut ret = Lot::new(); let mut ret = Lot::new();
let chat_loaded: Chat; let chat_loaded: Chat;
let chat = if let Some(chat) = chat { let chat = if let Some(chat) = chat {
chat chat
} else { } else {
if let Ok(chat) = Chat::load_from_db(msg.context, msg.chat_id) { if let Ok(chat) = Chat::load_from_db(context, msg.chat_id) {
chat_loaded = chat; chat_loaded = chat;
&chat_loaded &chat_loaded
} else { } else {
@@ -753,12 +749,13 @@ pub unsafe fn dc_msg_get_summary<'a>(msg: &mut Message<'a>, chat: Option<&Chat<'
None None
}; };
ret.fill(msg, chat, contact.as_ref(), msg.context); ret.fill(msg, chat, contact.as_ref(), context);
ret ret
} }
pub unsafe fn dc_msg_get_summarytext( pub unsafe fn dc_msg_get_summarytext(
context: &Context,
msg: &mut Message, msg: &mut Message,
approx_characters: usize, approx_characters: usize,
) -> *mut libc::c_char { ) -> *mut libc::c_char {
@@ -767,7 +764,7 @@ pub unsafe fn dc_msg_get_summarytext(
msg.text.as_ref(), msg.text.as_ref(),
&mut msg.param, &mut msg.param,
approx_characters, approx_characters,
msg.context, context,
) )
.strdup() .strdup()
} }
@@ -898,7 +895,7 @@ pub fn dc_msg_is_setupmessage(msg: &Message) -> bool {
msg.param.get_int(Param::Cmd) == Some(6) msg.param.get_int(Param::Cmd) == Some(6)
} }
pub unsafe fn dc_msg_get_setupcodebegin(msg: &Message) -> *mut libc::c_char { pub unsafe fn dc_msg_get_setupcodebegin(context: &Context, msg: &Message) -> *mut libc::c_char {
let mut filename: *mut libc::c_char = ptr::null_mut(); let mut filename: *mut libc::c_char = ptr::null_mut();
let mut buf: *mut libc::c_char = ptr::null_mut(); let mut buf: *mut libc::c_char = ptr::null_mut();
let mut buf_bytes: size_t = 0i32 as size_t; let mut buf_bytes: size_t = 0i32 as size_t;
@@ -908,11 +905,11 @@ pub unsafe fn dc_msg_get_setupcodebegin(msg: &Message) -> *mut libc::c_char {
let mut buf_setupcodebegin: *const libc::c_char = ptr::null(); let mut buf_setupcodebegin: *const libc::c_char = ptr::null();
let mut ret: *mut libc::c_char = ptr::null_mut(); let mut ret: *mut libc::c_char = ptr::null_mut();
if dc_msg_is_setupmessage(msg) { if dc_msg_is_setupmessage(msg) {
filename = dc_msg_get_file(msg); filename = dc_msg_get_file(context, msg);
if !(filename.is_null() || *filename.offset(0isize) as libc::c_int == 0i32) { if !(filename.is_null() || *filename.offset(0isize) as libc::c_int == 0i32) {
if !(0 if !(0
== dc_read_file( == dc_read_file(
msg.context, context,
filename, filename,
&mut buf as *mut *mut libc::c_char as *mut *mut libc::c_void, &mut buf as *mut *mut libc::c_char as *mut *mut libc::c_void,
&mut buf_bytes, &mut buf_bytes,
@@ -977,6 +974,7 @@ pub fn dc_msg_set_duration(msg: &mut Message, duration: libc::c_int) {
} }
pub fn dc_msg_latefiling_mediasize( pub fn dc_msg_latefiling_mediasize(
context: &Context,
msg: &mut Message, msg: &mut Message,
width: libc::c_int, width: libc::c_int,
height: libc::c_int, height: libc::c_int,
@@ -989,20 +987,20 @@ pub fn dc_msg_latefiling_mediasize(
if duration > 0 { if duration > 0 {
msg.param.set_int(Param::Duration, duration); msg.param.set_int(Param::Duration, duration);
} }
dc_msg_save_param_to_disk(msg); dc_msg_save_param_to_disk(context, msg);
} }
pub fn dc_msg_save_param_to_disk(msg: &mut Message) -> bool { pub fn dc_msg_save_param_to_disk(context: &Context, msg: &mut Message) -> bool {
sql::execute( sql::execute(
msg.context, context,
&msg.context.sql, &context.sql,
"UPDATE msgs SET param=? WHERE id=?;", "UPDATE msgs SET param=? WHERE id=?;",
params![msg.param.to_string(), msg.id as i32], params![msg.param.to_string(), msg.id as i32],
) )
.is_ok() .is_ok()
} }
pub fn dc_msg_new_load<'a>(context: &'a Context, msg_id: u32) -> Result<Message<'a>, Error> { pub fn dc_msg_new_load(context: &Context, msg_id: u32) -> Result<Message, Error> {
dc_msg_load_from_db(context, msg_id) dc_msg_load_from_db(context, msg_id)
} }
@@ -1321,7 +1319,7 @@ mod tests {
let chat = chat::create_by_contact_id(ctx, contact).unwrap(); let chat = chat::create_by_contact_id(ctx, contact).unwrap();
let mut msg = dc_msg_new(ctx, Viewtype::Text); let mut msg = dc_msg_new(Viewtype::Text);
let msg_id = chat::prepare_msg(ctx, chat, &mut msg).unwrap(); let msg_id = chat::prepare_msg(ctx, chat, &mut msg).unwrap();

View File

@@ -274,7 +274,7 @@ fn send_handshake_msg(
fingerprint: Option<String>, fingerprint: Option<String>,
grpid: impl AsRef<str>, grpid: impl AsRef<str>,
) { ) {
let mut msg = unsafe { dc_msg_new_untyped(context) }; let mut msg = dc_msg_new_untyped();
msg.type_0 = Viewtype::Text; msg.type_0 = Viewtype::Text;
msg.text = Some(format!("Secure-Join: {}", step)); msg.text = Some(format!("Secure-Join: {}", step));
msg.hidden = true; msg.hidden = true;