api(ffi): store reference-counted Context in dc_msg_t

The change is similar to the change done to dc_chat_t
in b5acbaa31c
This commit is contained in:
link2xt
2026-07-31 16:13:15 +00:00
committed by l
parent 77d2d037f2
commit abfc1b9a76

View File

@@ -1214,7 +1214,7 @@ pub unsafe extern "C" fn dc_set_draft(
let msg = if msg.is_null() {
None
} else {
let ffi_msg: &mut MessageWrapper = unsafe { &mut *msg };
let ffi_msg = unsafe { &mut *msg };
Some(&mut ffi_msg.message)
};
@@ -1236,7 +1236,7 @@ pub unsafe extern "C" fn dc_add_device_msg(
let msg = if msg.is_null() {
None
} else {
let ffi_msg: &mut MessageWrapper = unsafe { &mut *msg };
let ffi_msg = unsafe { &mut *msg };
Some(&mut ffi_msg.message)
};
@@ -1273,15 +1273,15 @@ pub unsafe extern "C" fn dc_get_draft(context: *mut dc_context_t, chat_id: u32)
eprintln!("ignoring careless call to dc_get_draft()");
return ptr::null_mut(); // NULL explicitly defined as "no draft"
}
let ctx = unsafe { &*context };
let context = unsafe { &*context };
match block_on(ChatId::new(chat_id).get_draft(ctx))
match block_on(ChatId::new(chat_id).get_draft(context))
.with_context(|| format!("Failed to get draft for chat #{chat_id}"))
.unwrap_or_default()
{
Some(draft) => {
let ffi_msg = MessageWrapper {
context,
context: context.clone(),
message: draft,
};
Box::into_raw(Box::new(ffi_msg))
@@ -2025,11 +2025,11 @@ pub unsafe extern "C" fn dc_get_msg(context: *mut dc_context_t, msg_id: u32) ->
eprintln!("ignoring careless call to dc_get_msg()");
return ptr::null_mut();
}
let ctx = unsafe { &*context };
let context = unsafe { &*context };
let message = match block_on(message::Message::load_from_db(ctx, MsgId::new(msg_id)))
let message = match block_on(message::Message::load_from_db(context, MsgId::new(msg_id)))
.with_context(|| format!("dc_get_msg could not rectieve msg_id {msg_id}"))
.log_err(ctx)
.log_err(context)
{
Ok(msg) => msg,
Err(_) => {
@@ -2041,7 +2041,10 @@ pub unsafe extern "C" fn dc_get_msg(context: *mut dc_context_t, msg_id: u32) ->
}
}
};
let ffi_msg = MessageWrapper { context, message };
let ffi_msg = MessageWrapper {
context: context.clone(),
message,
};
Box::into_raw(Box::new(ffi_msg))
}
@@ -3139,7 +3142,7 @@ pub unsafe extern "C" fn dc_chat_get_info_json(
/// context, but the Rust API does not, so the FFI layer needs to glue
/// these together.
pub struct MessageWrapper {
context: *const dc_context_t,
context: Context,
message: message::Message,
}
@@ -3157,7 +3160,7 @@ pub unsafe extern "C" fn dc_msg_new(
let context = unsafe { &*context };
let viewtype = from_prim(viewtype).expect(&format!("invalid viewtype = {viewtype}"));
let msg = MessageWrapper {
context,
context: context.clone(),
message: message::Message::new(viewtype),
};
Box::into_raw(Box::new(msg))
@@ -3294,10 +3297,9 @@ pub unsafe extern "C" fn dc_msg_get_file(msg: *mut dc_msg_t) -> *mut libc::c_cha
return "".strdup();
}
let ffi_msg = unsafe { &*msg };
let ctx = unsafe { &*ffi_msg.context };
ffi_msg
.message
.get_file(ctx)
.get_file(&ffi_msg.context)
.map(|p| p.to_string_lossy().strdup())
.unwrap_or_else(|| "".strdup())
}
@@ -3312,18 +3314,17 @@ pub unsafe extern "C" fn dc_msg_save_file(
return 0;
}
let ffi_msg = unsafe { &*msg };
let ctx = unsafe { &*ffi_msg.context };
let path = to_string_lossy(path);
let r = block_on(
ffi_msg
.message
.save_file(ctx, &std::path::PathBuf::from(path)),
.save_file(&ffi_msg.context, &std::path::PathBuf::from(path)),
);
match r {
Ok(()) => 1,
Err(_) => {
r.context("Failed to save file from message")
.log_err(ctx)
.log_err(&ffi_msg.context)
.unwrap_or_default();
0
}
@@ -3351,13 +3352,11 @@ pub unsafe extern "C" fn dc_msg_get_webxdc_blob(
return ptr::null_mut();
}
let ffi_msg = unsafe { &*msg };
let ctx = unsafe { &*ffi_msg.context };
let blob = block_on(async move {
let blob = block_on(
ffi_msg
.message
.get_webxdc_blob(ctx, &to_string_lossy(filename))
.await
});
.get_webxdc_blob(&ffi_msg.context, &to_string_lossy(filename)),
);
match blob {
Ok(blob) => unsafe {
*ret_bytes = blob.len();
@@ -3379,16 +3378,18 @@ pub unsafe extern "C" fn dc_msg_get_webxdc_info(msg: *mut dc_msg_t) -> *mut libc
return "".strdup();
}
let ffi_msg = unsafe { &*msg };
let ctx = unsafe { &*ffi_msg.context };
let Ok(info) = block_on(ffi_msg.message.get_webxdc_info(ctx))
let Ok(info) = block_on(ffi_msg.message.get_webxdc_info(&ffi_msg.context))
.context("dc_msg_get_webxdc_info() failed to get info")
.log_err(ctx)
.log_err(&ffi_msg.context)
else {
return "".strdup();
};
serde_json::to_string(&info)
.unwrap_or_log_default(ctx, "dc_msg_get_webxdc_info() failed to serialise to json")
.unwrap_or_log_default(
&ffi_msg.context,
"dc_msg_get_webxdc_info() failed to serialise to json",
)
.strdup()
}
@@ -3413,10 +3414,9 @@ pub unsafe extern "C" fn dc_msg_get_filebytes(msg: *mut dc_msg_t) -> u64 {
return 0;
}
let ffi_msg = unsafe { &*msg };
let ctx = unsafe { &*ffi_msg.context };
block_on(ffi_msg.message.get_filebytes(ctx))
.unwrap_or_log_default(ctx, "Cannot get file size")
block_on(ffi_msg.message.get_filebytes(&ffi_msg.context))
.unwrap_or_log_default(&ffi_msg.context, "Cannot get file size")
.unwrap_or_default()
}
@@ -3506,11 +3506,10 @@ pub unsafe extern "C" fn dc_msg_get_summary(
Some(&ffi_chat.chat)
};
let ffi_msg = unsafe { &mut *msg };
let ctx = unsafe { &*ffi_msg.context };
let summary = block_on(ffi_msg.message.get_summary(ctx, maybe_chat))
let summary = block_on(ffi_msg.message.get_summary(&ffi_msg.context, maybe_chat))
.context("dc_msg_get_summary failed")
.log_err(ctx)
.log_err(&ffi_msg.context)
.unwrap_or_default();
Box::into_raw(Box::new(summary.into()))
}
@@ -3525,11 +3524,10 @@ pub unsafe extern "C" fn dc_msg_get_summarytext(
return "".strdup();
}
let ffi_msg = unsafe { &mut *msg };
let ctx = unsafe { &*ffi_msg.context };
let summary = block_on(ffi_msg.message.get_summary(ctx, None))
let summary = block_on(ffi_msg.message.get_summary(&ffi_msg.context, None))
.context("dc_msg_get_summarytext failed")
.log_err(ctx)
.log_err(&ffi_msg.context)
.unwrap_or_default();
match usize::try_from(approx_characters) {
Ok(chars) => summary.truncated_text(chars).strdup(),
@@ -3625,8 +3623,7 @@ pub unsafe extern "C" fn dc_msg_get_info_contact_id(msg: *mut dc_msg_t) -> u32 {
return 0;
}
let ffi_msg = unsafe { &*msg };
let context = unsafe { &*ffi_msg.context };
block_on(ffi_msg.message.get_info_contact_id(context))
block_on(ffi_msg.message.get_info_contact_id(&ffi_msg.context))
.unwrap_or_default()
.map(|id| id.to_u32())
.unwrap_or_default()
@@ -3710,18 +3707,17 @@ pub unsafe extern "C" fn dc_msg_set_file_and_deduplicate(
return;
}
let ffi_msg = unsafe { &mut *msg };
let ctx = unsafe { &*ffi_msg.context };
ffi_msg
.message
.set_file_and_deduplicate(
ctx,
&ffi_msg.context,
unsafe { as_path(file) },
to_opt_string_lossy(name).as_deref(),
to_opt_string_lossy(filemime).as_deref(),
)
.context("Failed to set file")
.log_err(ctx)
.log_err(&ffi_msg.context)
.ok();
}
@@ -3775,15 +3771,14 @@ pub unsafe extern "C" fn dc_msg_latefiling_mediasize(
return;
}
let ffi_msg = unsafe { &mut *msg };
let ctx = unsafe { &*ffi_msg.context };
block_on({
ffi_msg
.message
.latefiling_mediasize(ctx, width, height, duration)
.latefiling_mediasize(&ffi_msg.context, width, height, duration)
})
.context("Cannot set media size")
.log_err(ctx)
.log_err(&ffi_msg.context)
.ok();
}
@@ -3811,17 +3806,16 @@ pub unsafe extern "C" fn dc_msg_set_quote(msg: *mut dc_msg_t, quote: *const dc_m
None
} else {
let ffi_quote = unsafe { &*quote };
if ffi_msg.context != ffi_quote.context {
if ffi_msg.context.get_id() != ffi_quote.context.get_id() {
eprintln!("ignoring attempt to quote message from a different context");
return;
}
Some(&ffi_quote.message)
};
let context = unsafe { &*ffi_msg.context };
block_on(ffi_msg.message.set_quote(context, quote_msg))
block_on(ffi_msg.message.set_quote(&ffi_msg.context, quote_msg))
.context("failed to set quote")
.log_err(context)
.log_err(&ffi_msg.context)
.ok();
}
@@ -3831,7 +3825,7 @@ pub unsafe extern "C" fn dc_msg_get_quoted_text(msg: *const dc_msg_t) -> *mut li
eprintln!("ignoring careless call to dc_msg_get_quoted_text()");
return ptr::null_mut();
}
let ffi_msg: &MessageWrapper = unsafe { &*msg };
let ffi_msg = unsafe { &*msg };
ffi_msg
.message
.quoted_text()
@@ -3844,15 +3838,17 @@ pub unsafe extern "C" fn dc_msg_get_quoted_msg(msg: *const dc_msg_t) -> *mut dc_
eprintln!("ignoring careless call to dc_get_quoted_msg()");
return ptr::null_mut();
}
let ffi_msg: &MessageWrapper = unsafe { &*msg };
let context = unsafe { &*ffi_msg.context };
let res = block_on(ffi_msg.message.quoted_message(context))
let ffi_msg = unsafe { &*msg };
let res = block_on(ffi_msg.message.quoted_message(&ffi_msg.context))
.context("failed to get quoted message")
.log_err(context)
.log_err(&ffi_msg.context)
.unwrap_or(None);
match res {
Some(message) => Box::into_raw(Box::new(MessageWrapper { context, message })),
Some(message) => Box::into_raw(Box::new(MessageWrapper {
context: ffi_msg.context.clone(),
message,
})),
None => ptr::null_mut(),
}
}
@@ -3863,15 +3859,17 @@ pub unsafe extern "C" fn dc_msg_get_parent(msg: *const dc_msg_t) -> *mut dc_msg_
eprintln!("ignoring careless call to dc_msg_get_parent()");
return ptr::null_mut();
}
let ffi_msg: &MessageWrapper = unsafe { &*msg };
let context = unsafe { &*ffi_msg.context };
let res = block_on(ffi_msg.message.parent(context))
let ffi_msg = unsafe { &*msg };
let res = block_on(ffi_msg.message.parent(&ffi_msg.context))
.context("failed to get parent message")
.log_err(context)
.log_err(&ffi_msg.context)
.unwrap_or(None);
match res {
Some(message) => Box::into_raw(Box::new(MessageWrapper { context, message })),
Some(message) => Box::into_raw(Box::new(MessageWrapper {
context: ffi_msg.context.clone(),
message,
})),
None => ptr::null_mut(),
}
}
@@ -3882,11 +3880,10 @@ pub unsafe extern "C" fn dc_msg_get_original_msg_id(msg: *const dc_msg_t) -> u32
eprintln!("ignoring careless call to dc_msg_get_original_msg_id()");
return 0;
}
let ffi_msg: &MessageWrapper = unsafe { &*msg };
let context = unsafe { &*ffi_msg.context };
block_on(ffi_msg.message.get_original_msg_id(context))
let ffi_msg = unsafe { &*msg };
block_on(ffi_msg.message.get_original_msg_id(&ffi_msg.context))
.context("failed to get original message")
.log_err(context)
.log_err(&ffi_msg.context)
.unwrap_or_default()
.map(|id| id.to_u32())
.unwrap_or(0)
@@ -3898,11 +3895,10 @@ pub unsafe extern "C" fn dc_msg_get_saved_msg_id(msg: *const dc_msg_t) -> u32 {
eprintln!("ignoring careless call to dc_msg_get_saved_msg_id()");
return 0;
}
let ffi_msg: &MessageWrapper = unsafe { &*msg };
let context = unsafe { &*ffi_msg.context };
block_on(ffi_msg.message.get_saved_msg_id(context))
let ffi_msg = unsafe { &*msg };
block_on(ffi_msg.message.get_saved_msg_id(&ffi_msg.context))
.context("failed to get original message")
.log_err(context)
.log_err(&ffi_msg.context)
.unwrap_or_default()
.map(|id| id.to_u32())
.unwrap_or(0)