mirror of
https://github.com/chatmail/core.git
synced 2026-05-03 21:36:29 +03:00
refactor(message): remove unsafe and c types from the Message api
This commit is contained in:
committed by
holger krekel
parent
1265016a55
commit
987f12740e
@@ -2282,7 +2282,7 @@ pub unsafe extern "C" fn dc_msg_get_text(msg: *mut dc_msg_t) -> *mut libc::c_cha
|
||||
return dc_strdup(ptr::null());
|
||||
}
|
||||
let ffi_msg = &*msg;
|
||||
ffi_msg.message.get_text()
|
||||
ffi_msg.message.get_text().unwrap_or_default().strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2312,7 +2312,7 @@ pub unsafe extern "C" fn dc_msg_get_filename(msg: *mut dc_msg_t) -> *mut libc::c
|
||||
return dc_strdup(ptr::null());
|
||||
}
|
||||
let ffi_msg = &*msg;
|
||||
ffi_msg.message.get_filename()
|
||||
ffi_msg.message.get_filename().unwrap_or_default().strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2420,7 +2420,8 @@ pub unsafe extern "C" fn dc_msg_get_summarytext(
|
||||
.message
|
||||
.get_summarytext(ctx, approx_characters.try_into().unwrap())
|
||||
})
|
||||
.unwrap_or_else(|_| "".strdup())
|
||||
.unwrap_or_default()
|
||||
.strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2430,7 +2431,7 @@ pub unsafe extern "C" fn dc_msg_has_deviating_timestamp(msg: *mut dc_msg_t) -> l
|
||||
return 0;
|
||||
}
|
||||
let ffi_msg = &*msg;
|
||||
ffi_msg.message.has_deviating_timestamp()
|
||||
ffi_msg.message.has_deviating_timestamp().into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2512,8 +2513,9 @@ pub unsafe extern "C" fn dc_msg_get_setupcodebegin(msg: *mut dc_msg_t) -> *mut l
|
||||
let ffi_msg = &*msg;
|
||||
let ffi_context = &*ffi_msg.context;
|
||||
ffi_context
|
||||
.with_inner(|ctx| ffi_msg.message.get_setupcodebegin(ctx))
|
||||
.unwrap_or_else(|_| "".strdup())
|
||||
.with_inner(|ctx| ffi_msg.message.get_setupcodebegin(ctx).unwrap_or_default())
|
||||
.unwrap_or_default()
|
||||
.strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2524,7 +2526,7 @@ pub unsafe extern "C" fn dc_msg_set_text(msg: *mut dc_msg_t, text: *mut libc::c_
|
||||
}
|
||||
let ffi_msg = &mut *msg;
|
||||
// TODO: {text} equal to NULL is treated as "", which is strange. Does anyone rely on it?
|
||||
ffi_msg.message.set_text(text)
|
||||
ffi_msg.message.set_text(as_opt_str(text).map(Into::into))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2533,12 +2535,12 @@ pub unsafe extern "C" fn dc_msg_set_file(
|
||||
file: *mut libc::c_char,
|
||||
filemime: *mut libc::c_char,
|
||||
) {
|
||||
if msg.is_null() {
|
||||
if msg.is_null() || file.is_null() {
|
||||
eprintln!("ignoring careless call to dc_msg_set_file()");
|
||||
return;
|
||||
}
|
||||
let ffi_msg = &mut *msg;
|
||||
ffi_msg.message.set_file(file, filemime)
|
||||
ffi_msg.message.set_file(as_str(file), as_opt_str(filemime))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -238,7 +238,7 @@ unsafe fn log_msg(context: &Context, prefix: impl AsRef<str>, msg: &Message) {
|
||||
if msg.has_location() { "📍" } else { "" },
|
||||
&contact_name,
|
||||
contact_id,
|
||||
as_str(msgtext),
|
||||
msgtext.unwrap_or_default(),
|
||||
if msg.is_starred() { "★" } else { "" },
|
||||
if msg.get_from_id() == 1 as libc::c_uint {
|
||||
""
|
||||
@@ -253,7 +253,6 @@ unsafe fn log_msg(context: &Context, prefix: impl AsRef<str>, msg: &Message) {
|
||||
statestr,
|
||||
&temp2,
|
||||
);
|
||||
free(msgtext as *mut libc::c_void);
|
||||
}
|
||||
|
||||
unsafe fn log_msglist(context: &Context, msglist: &Vec<u32>) -> Result<(), Error> {
|
||||
@@ -469,9 +468,8 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
println!(
|
||||
"The setup code for setup message Msg#{} starts with: {}",
|
||||
msg_id,
|
||||
as_str(setupcodebegin),
|
||||
setupcodebegin.unwrap_or_default(),
|
||||
);
|
||||
free(setupcodebegin as *mut libc::c_void);
|
||||
} else {
|
||||
bail!("Msg#{} is no setup message.", msg_id,);
|
||||
}
|
||||
@@ -826,9 +824,9 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
} else {
|
||||
Viewtype::File
|
||||
});
|
||||
msg.set_file(arg1_c, ptr::null());
|
||||
msg.set_file(arg1, None);
|
||||
if !arg2.is_empty() {
|
||||
msg.set_text(arg2_c);
|
||||
msg.set_text(Some(arg2.to_string()));
|
||||
}
|
||||
chat::send_msg(context, sel_chat.as_ref().unwrap().get_id(), &mut msg)?;
|
||||
}
|
||||
@@ -851,7 +849,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
|
||||
if !arg1.is_empty() {
|
||||
let mut draft = Message::new(Viewtype::Text);
|
||||
draft.set_text(arg1_c);
|
||||
draft.set_text(Some(arg1.to_string()));
|
||||
chat::set_draft(
|
||||
context,
|
||||
sel_chat.as_ref().unwrap().get_id(),
|
||||
|
||||
11
src/chat.rs
11
src/chat.rs
@@ -1,4 +1,3 @@
|
||||
use std::ffi::CString;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::chatlist::*;
|
||||
@@ -1277,9 +1276,7 @@ pub unsafe fn create_group_chat(
|
||||
) -> Result<u32, Error> {
|
||||
ensure!(!chat_name.as_ref().is_empty(), "Invalid chat name");
|
||||
|
||||
let draft_txt =
|
||||
CString::new(context.stock_string_repl_str(StockMessage::NewGroupDraft, &chat_name))
|
||||
.unwrap();
|
||||
let draft_txt = context.stock_string_repl_str(StockMessage::NewGroupDraft, &chat_name);
|
||||
let grpid = dc_create_id();
|
||||
|
||||
sql::execute(
|
||||
@@ -1302,7 +1299,7 @@ pub unsafe fn create_group_chat(
|
||||
if chat_id != 0 {
|
||||
if add_to_chat_contacts_table(context, chat_id, 1) {
|
||||
let mut draft_msg = Message::new(Viewtype::Text);
|
||||
draft_msg.set_text(draft_txt.as_ptr());
|
||||
draft_msg.set_text(Some(draft_txt));
|
||||
set_draft_raw(context, chat_id, &mut draft_msg);
|
||||
}
|
||||
|
||||
@@ -1911,12 +1908,12 @@ mod tests {
|
||||
let t = dummy_context();
|
||||
let chat_id = create_by_contact_id(&t.ctx, DC_CONTACT_ID_SELF).unwrap();
|
||||
let mut msg = Message::new(Viewtype::Text);
|
||||
msg.set_text(b"hello\x00" as *const u8 as *const libc::c_char);
|
||||
msg.set_text(Some("hello".to_string()));
|
||||
set_draft(&t.ctx, chat_id, Some(&mut msg));
|
||||
let draft = get_draft(&t.ctx, chat_id).unwrap().unwrap();
|
||||
let msg_text = msg.get_text();
|
||||
let draft_text = draft.get_text();
|
||||
assert_eq!(as_str(msg_text), as_str(draft_text));
|
||||
assert_eq!(msg_text, draft_text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ const DC_MAX_GET_INFO_LEN: usize = 100000;
|
||||
|
||||
pub const DC_CONTACT_ID_UNDEFINED: u32 = 0;
|
||||
pub const DC_CONTACT_ID_SELF: u32 = 1;
|
||||
const DC_CONTACT_ID_DEVICE: u32 = 2;
|
||||
pub const DC_CONTACT_ID_DEVICE: u32 = 2;
|
||||
pub const DC_CONTACT_ID_LAST_SPECIAL: u32 = 9;
|
||||
|
||||
pub const DC_CREATE_MVBOX: usize = 1;
|
||||
|
||||
@@ -917,7 +917,7 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut MimeFactory
|
||||
.stock_str(StockMessage::EncryptedMsg)
|
||||
.into_owned()
|
||||
} else {
|
||||
to_string(factory.msg.get_summarytext(context, 32))
|
||||
factory.msg.get_summarytext(context, 32)
|
||||
};
|
||||
let p2 = factory
|
||||
.context
|
||||
|
||||
131
src/message.rs
131
src/message.rs
@@ -235,44 +235,35 @@ impl Message {
|
||||
self.timestamp_sort
|
||||
}
|
||||
|
||||
pub unsafe fn get_text(&self) -> *mut libc::c_char {
|
||||
if let Some(ref text) = self.text {
|
||||
dc_truncate(text, 30000, false).strdup()
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
}
|
||||
pub fn get_text(&self) -> Option<String> {
|
||||
self.text
|
||||
.as_ref()
|
||||
.map(|text| dc_truncate(text, 30000, false).to_string())
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe fn get_filename(&self) -> *mut libc::c_char {
|
||||
let mut ret = ptr::null_mut();
|
||||
|
||||
if let Some(file) = self.param.get(Param::File) {
|
||||
ret = dc_get_filename(file);
|
||||
}
|
||||
if !ret.is_null() {
|
||||
ret
|
||||
} else {
|
||||
dc_strdup(0 as *const libc::c_char)
|
||||
}
|
||||
pub fn get_filename(&self) -> Option<String> {
|
||||
self.param
|
||||
.get(Param::File)
|
||||
.and_then(|file| Path::new(file).file_name())
|
||||
.map(|name| name.to_string_lossy().to_string())
|
||||
}
|
||||
|
||||
pub fn get_filebytes(&self, context: &Context) -> u64 {
|
||||
if let Some(file) = self.param.get(Param::File) {
|
||||
return dc_get_filebytes(context, &file);
|
||||
}
|
||||
0
|
||||
self.param
|
||||
.get(Param::File)
|
||||
.map(|file| dc_get_filebytes(context, &file))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn get_width(&self) -> libc::c_int {
|
||||
pub fn get_width(&self) -> i32 {
|
||||
self.param.get_int(Param::Width).unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn get_height(&self) -> libc::c_int {
|
||||
pub fn get_height(&self) -> i32 {
|
||||
self.param.get_int(Param::Height).unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn get_duration(&self) -> libc::c_int {
|
||||
pub fn get_duration(&self) -> i32 {
|
||||
self.param.get_int(Param::Duration).unwrap_or_default()
|
||||
}
|
||||
|
||||
@@ -286,13 +277,11 @@ impl Message {
|
||||
let chat_loaded: Chat;
|
||||
let chat = if let Some(chat) = chat {
|
||||
chat
|
||||
} else if let Ok(chat) = Chat::load_from_db(context, self.chat_id) {
|
||||
chat_loaded = chat;
|
||||
&chat_loaded
|
||||
} else {
|
||||
if let Ok(chat) = Chat::load_from_db(context, self.chat_id) {
|
||||
chat_loaded = chat;
|
||||
&chat_loaded
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
let contact = if self.from_id != DC_CONTACT_ID_SELF as libc::c_uint
|
||||
@@ -308,11 +297,7 @@ impl Message {
|
||||
ret
|
||||
}
|
||||
|
||||
pub unsafe fn get_summarytext(
|
||||
&mut self,
|
||||
context: &Context,
|
||||
approx_characters: usize,
|
||||
) -> *mut libc::c_char {
|
||||
pub fn get_summarytext(&mut self, context: &Context, approx_characters: usize) -> String {
|
||||
get_summarytext_by_raw(
|
||||
self.type_0,
|
||||
self.text.as_ref(),
|
||||
@@ -320,15 +305,14 @@ impl Message {
|
||||
approx_characters,
|
||||
context,
|
||||
)
|
||||
.strdup()
|
||||
}
|
||||
|
||||
pub unsafe fn has_deviating_timestamp(&self) -> libc::c_int {
|
||||
pub fn has_deviating_timestamp(&self) -> bool {
|
||||
let cnv_to_local = dc_gm2local_offset();
|
||||
let sort_timestamp = self.get_sort_timestamp() as i64 + cnv_to_local;
|
||||
let send_timestamp = self.get_timestamp() as i64 + cnv_to_local;
|
||||
|
||||
(sort_timestamp / 86400 != send_timestamp / 86400) as libc::c_int
|
||||
sort_timestamp / 86400 != send_timestamp / 86400
|
||||
}
|
||||
|
||||
pub fn is_sent(&self) -> bool {
|
||||
@@ -345,8 +329,8 @@ impl Message {
|
||||
|
||||
pub fn is_info(&self) -> bool {
|
||||
let cmd = self.param.get_cmd();
|
||||
self.from_id == 2i32 as libc::c_uint
|
||||
|| self.to_id == 2i32 as libc::c_uint
|
||||
self.from_id == DC_CONTACT_ID_DEVICE as libc::c_uint
|
||||
|| self.to_id == DC_CONTACT_ID_DEVICE as libc::c_uint
|
||||
|| cmd != SystemMessage::Unknown && cmd != SystemMessage::AutocryptSetupMessage
|
||||
}
|
||||
|
||||
@@ -362,15 +346,19 @@ impl Message {
|
||||
self.param.get_cmd() == SystemMessage::AutocryptSetupMessage
|
||||
}
|
||||
|
||||
pub unsafe fn get_setupcodebegin(&self, context: &Context) -> *mut libc::c_char {
|
||||
// just a pointer inside buf, MUST NOT be free()'d
|
||||
let mut buf_headerline: *const libc::c_char = ptr::null();
|
||||
// just a pointer inside buf, MUST NOT be free()'d
|
||||
let mut buf_setupcodebegin: *const libc::c_char = ptr::null();
|
||||
let mut ret: *mut libc::c_char = ptr::null_mut();
|
||||
pub fn get_setupcodebegin(&self, context: &Context) -> Option<String> {
|
||||
if self.is_setupmessage() {
|
||||
if let Some(filename) = self.get_file(context) {
|
||||
if let Some(mut buf) = dc_read_file_safe(context, filename) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(filename) = self.get_file(context) {
|
||||
if let Some(mut buf) = dc_read_file_safe(context, filename) {
|
||||
unsafe {
|
||||
// just a pointer inside buf, MUST NOT be free()'d
|
||||
let mut buf_headerline: *const libc::c_char = ptr::null();
|
||||
// just a pointer inside buf, MUST NOT be free()'d
|
||||
let mut buf_setupcodebegin: *const libc::c_char = ptr::null();
|
||||
|
||||
if dc_split_armored_data(
|
||||
buf.as_mut_ptr().cast(),
|
||||
&mut buf_headerline,
|
||||
@@ -383,50 +371,41 @@ impl Message {
|
||||
) == 0
|
||||
&& !buf_setupcodebegin.is_null()
|
||||
{
|
||||
ret = dc_strdup(buf_setupcodebegin)
|
||||
return Some(to_string(buf_setupcodebegin));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !ret.is_null() {
|
||||
ret
|
||||
} else {
|
||||
dc_strdup(0 as *const libc::c_char)
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn set_text(&mut self, text: Option<String>) {
|
||||
self.text = text;
|
||||
}
|
||||
|
||||
pub fn set_file(&mut self, file: impl AsRef<str>, filemime: Option<&str>) {
|
||||
self.param.set(Param::File, file);
|
||||
if let Some(filemime) = filemime {
|
||||
self.param.set(Param::MimeType, filemime);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_text(&mut self, text: *const libc::c_char) {
|
||||
self.text = if text.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(to_string(text))
|
||||
};
|
||||
}
|
||||
|
||||
pub fn set_file(&mut self, file: *const libc::c_char, filemime: *const libc::c_char) {
|
||||
if !file.is_null() {
|
||||
self.param.set(Param::File, as_str(file));
|
||||
}
|
||||
if !filemime.is_null() {
|
||||
self.param.set(Param::MimeType, as_str(filemime));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_dimension(&mut self, width: libc::c_int, height: libc::c_int) {
|
||||
pub fn set_dimension(&mut self, width: i32, height: i32) {
|
||||
self.param.set_int(Param::Width, width);
|
||||
self.param.set_int(Param::Height, height);
|
||||
}
|
||||
|
||||
pub fn set_duration(&mut self, duration: libc::c_int) {
|
||||
pub fn set_duration(&mut self, duration: i32) {
|
||||
self.param.set_int(Param::Duration, duration);
|
||||
}
|
||||
|
||||
pub fn latefiling_mediasize(
|
||||
&mut self,
|
||||
context: &Context,
|
||||
width: libc::c_int,
|
||||
height: libc::c_int,
|
||||
duration: libc::c_int,
|
||||
width: i32,
|
||||
height: i32,
|
||||
duration: i32,
|
||||
) {
|
||||
if width > 0 && height > 0 {
|
||||
self.param.set_int(Param::Width, width);
|
||||
|
||||
Reference in New Issue
Block a user