mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
Introduce new enum: Viewtype
With this change, kind of message is represented by value of enum `Viewtype' instead of raw libc::c_int, providing more type safety. This enum replaces DC_MSG_* constants. The only way to create `Viewtype' from libc::c_int is smart constructor. With this change, functions `dc_get_chat_media' and `dc_get_next_media' became less forgiving about invalid message type arguments. Previously, invalid message types were implicitly interpreted as 0 (Viewtype::Unknown). Now, function calls with invalid message type arguments are rejected (error code returned) on FFI boundary. Additionally, when `Viewtype' is read from database, it is checked to have sensible value. No tests assumed forgiving behaviour.
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -507,6 +507,7 @@ dependencies = [
|
||||
"deltachat 1.0.0-alpha.3",
|
||||
"human-panic 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -18,6 +18,7 @@ crate-type = ["cdylib", "staticlib"]
|
||||
deltachat = { path = "../", default-features = false }
|
||||
libc = "0.2"
|
||||
human-panic = "1.0.1"
|
||||
num-traits = "0.2.6"
|
||||
|
||||
[features]
|
||||
default = ["vendored", "nightly", "ringbuf"]
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate human_panic;
|
||||
extern crate num_traits;
|
||||
|
||||
use num_traits::{FromPrimitive, ToPrimitive};
|
||||
use std::ptr;
|
||||
use std::str::FromStr;
|
||||
|
||||
use deltachat::*;
|
||||
@@ -458,6 +461,14 @@ pub unsafe extern "C" fn dc_marknoticed_all_chats(context: *mut dc_context_t) {
|
||||
dc_chat::dc_marknoticed_all_chats(context);
|
||||
}
|
||||
|
||||
fn from_prim<S, T>(s: S) -> Option<T>
|
||||
where
|
||||
T: FromPrimitive,
|
||||
S: Into<i64>,
|
||||
{
|
||||
FromPrimitive::from_i64(s.into())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_get_chat_media(
|
||||
context: *mut dc_context_t,
|
||||
@@ -469,7 +480,15 @@ pub unsafe extern "C" fn dc_get_chat_media(
|
||||
assert!(!context.is_null());
|
||||
let context = &*context;
|
||||
|
||||
dc_chat::dc_get_chat_media(context, chat_id, msg_type, or_msg_type2, or_msg_type3)
|
||||
if let (Some(msg_type), Some(or_msg_type2), Some(or_msg_type3)) = (
|
||||
from_prim(msg_type),
|
||||
from_prim(or_msg_type2),
|
||||
from_prim(or_msg_type3),
|
||||
) {
|
||||
dc_chat::dc_get_chat_media(context, chat_id, msg_type, or_msg_type2, or_msg_type3)
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -484,7 +503,15 @@ pub unsafe extern "C" fn dc_get_next_media(
|
||||
assert!(!context.is_null());
|
||||
let context = &*context;
|
||||
|
||||
dc_chat::dc_get_next_media(context, msg_id, dir, msg_type, or_msg_type2, or_msg_type3)
|
||||
if let (Some(msg_type), Some(or_msg_type2), Some(or_msg_type3)) = (
|
||||
from_prim(msg_type),
|
||||
from_prim(or_msg_type2),
|
||||
from_prim(or_msg_type3),
|
||||
) {
|
||||
dc_chat::dc_get_next_media(context, msg_id, dir, msg_type, or_msg_type2, or_msg_type3)
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -1236,8 +1263,11 @@ pub unsafe extern "C" fn dc_msg_new<'a>(
|
||||
) -> *mut dc_msg::dc_msg_t<'a> {
|
||||
assert!(!context.is_null());
|
||||
let context = &*context;
|
||||
|
||||
dc_msg::dc_msg_new(context, viewtype)
|
||||
if let Some(viewtype) = from_prim(viewtype) {
|
||||
dc_msg::dc_msg_new(context, viewtype)
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -1268,6 +1298,8 @@ pub unsafe extern "C" fn dc_msg_get_chat_id(msg: *mut dc_msg::dc_msg_t) -> u32 {
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_msg_get_viewtype(msg: *mut dc_msg::dc_msg_t) -> libc::c_int {
|
||||
dc_msg::dc_msg_get_viewtype(msg)
|
||||
.to_i64()
|
||||
.expect("impossible: Viewtype -> i64 conversion failed") as libc::c_int
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -963,7 +963,14 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
||||
ensure!(!arg1.is_empty() && !arg2.is_empty(), "No file given.");
|
||||
|
||||
let msg_0 = dc_msg_new(context, if arg0 == "sendimage" { 20 } else { 60 });
|
||||
let msg_0 = dc_msg_new(
|
||||
context,
|
||||
if arg0 == "sendimage" {
|
||||
Viewtype::Image
|
||||
} else {
|
||||
Viewtype::File
|
||||
},
|
||||
);
|
||||
dc_msg_set_file(msg_0, arg1_c, 0 as *const libc::c_char);
|
||||
dc_msg_set_text(msg_0, arg2_c);
|
||||
dc_send_msg(context, dc_chat_get_id(sel_chat), msg_0);
|
||||
@@ -990,7 +997,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
||||
|
||||
if !arg1.is_empty() {
|
||||
let draft_0 = dc_msg_new(context, 10);
|
||||
let draft_0 = dc_msg_new(context, Viewtype::Text);
|
||||
dc_msg_set_text(draft_0, arg1_c);
|
||||
dc_set_draft(context, dc_chat_get_id(sel_chat), draft_0);
|
||||
dc_msg_unref(draft_0);
|
||||
@@ -1003,7 +1010,13 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
"listmedia" => {
|
||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
||||
|
||||
let images = dc_get_chat_media(context, dc_chat_get_id(sel_chat), 20, 21, 50);
|
||||
let images = dc_get_chat_media(
|
||||
context,
|
||||
dc_chat_get_id(sel_chat),
|
||||
Viewtype::Image,
|
||||
Viewtype::Gif,
|
||||
Viewtype::Video,
|
||||
);
|
||||
let icnt: libc::c_int = dc_array_get_cnt(images) as libc::c_int;
|
||||
println!("{} images or videos: ", icnt);
|
||||
for i in 0..icnt {
|
||||
|
||||
119
src/constants.rs
119
src/constants.rs
@@ -1,5 +1,9 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
//! Constants
|
||||
#![allow(non_camel_case_types)]
|
||||
use num_traits::{FromPrimitive, ToPrimitive};
|
||||
use rusqlite as sql;
|
||||
use rusqlite::types::*;
|
||||
use std::fmt;
|
||||
|
||||
pub const DC_VERSION_STR: &'static [u8; 14] = b"1.0.0-alpha.3\x00";
|
||||
|
||||
@@ -96,46 +100,6 @@ pub const DC_TEXT1_SELF: usize = 3;
|
||||
|
||||
pub const DC_CREATE_MVBOX: usize = 1;
|
||||
|
||||
/// Text message.
|
||||
/// The text of the message is set using dc_msg_set_text()
|
||||
/// and retrieved with dc_msg_get_text().
|
||||
pub const DC_MSG_TEXT: i32 = 10;
|
||||
|
||||
/// Image message.
|
||||
/// If the image is an animated GIF, the type DC_MSG_GIF should be used.
|
||||
/// File, width and height are set via dc_msg_set_file(), dc_msg_set_dimension
|
||||
/// and retrieved via dc_msg_set_file(), dc_msg_set_dimension().
|
||||
pub const DC_MSG_IMAGE: i32 = 20;
|
||||
|
||||
/// Animated GIF message.
|
||||
/// File, width and height are set via dc_msg_set_file(), dc_msg_set_dimension()
|
||||
/// and retrieved via dc_msg_get_file(), dc_msg_get_width(), dc_msg_get_height().
|
||||
pub const DC_MSG_GIF: i32 = 21;
|
||||
|
||||
/// Message containing an Audio file.
|
||||
/// File and duration are set via dc_msg_set_file(), dc_msg_set_duration()
|
||||
/// and retrieved via dc_msg_get_file(), dc_msg_get_duration().
|
||||
pub const DC_MSG_AUDIO: i32 = 40;
|
||||
|
||||
/// A voice message that was directly recorded by the user.
|
||||
/// For all other audio messages, the type #DC_MSG_AUDIO should be used.
|
||||
/// File and duration are set via dc_msg_set_file(), dc_msg_set_duration()
|
||||
/// and retrieved via dc_msg_get_file(), dc_msg_get_duration()
|
||||
pub const DC_MSG_VOICE: i32 = 41;
|
||||
|
||||
/// Video messages.
|
||||
/// File, width, height and durarion
|
||||
/// are set via dc_msg_set_file(), dc_msg_set_dimension(), dc_msg_set_duration()
|
||||
/// and retrieved via
|
||||
/// dc_msg_get_file(), dc_msg_get_width(),
|
||||
/// dc_msg_get_height(), dc_msg_get_duration().
|
||||
pub const DC_MSG_VIDEO: i32 = 50;
|
||||
|
||||
/// Message containing any file, eg. a PDF.
|
||||
/// The file is set via dc_msg_set_file()
|
||||
/// and retrieved via dc_msg_get_file().
|
||||
pub const DC_MSG_FILE: i32 = 60;
|
||||
|
||||
// Flags for configuring IMAP and SMTP servers.
|
||||
// These flags are optional
|
||||
// and may be set together with the username, password etc.
|
||||
@@ -183,6 +147,79 @@ pub const DC_LP_IMAP_SOCKET_FLAGS: usize =
|
||||
pub const DC_LP_SMTP_SOCKET_FLAGS: usize =
|
||||
(DC_LP_SMTP_SOCKET_STARTTLS | DC_LP_SMTP_SOCKET_SSL | DC_LP_SMTP_SOCKET_PLAIN);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
||||
#[repr(i32)]
|
||||
pub enum Viewtype {
|
||||
Unknown = 0,
|
||||
/// Text message.
|
||||
/// The text of the message is set using dc_msg_set_text()
|
||||
/// and retrieved with dc_msg_get_text().
|
||||
Text = 10,
|
||||
|
||||
/// Image message.
|
||||
/// If the image is an animated GIF, the type DC_MSG_GIF should be used.
|
||||
/// File, width and height are set via dc_msg_set_file(), dc_msg_set_dimension
|
||||
/// and retrieved via dc_msg_set_file(), dc_msg_set_dimension().
|
||||
Image = 20,
|
||||
|
||||
/// Animated GIF message.
|
||||
/// File, width and height are set via dc_msg_set_file(), dc_msg_set_dimension()
|
||||
/// and retrieved via dc_msg_get_file(), dc_msg_get_width(), dc_msg_get_height().
|
||||
Gif = 21,
|
||||
|
||||
/// Message containing an Audio file.
|
||||
/// File and duration are set via dc_msg_set_file(), dc_msg_set_duration()
|
||||
/// and retrieved via dc_msg_get_file(), dc_msg_get_duration().
|
||||
Audio = 40,
|
||||
|
||||
/// A voice message that was directly recorded by the user.
|
||||
/// For all other audio messages, the type #DC_MSG_AUDIO should be used.
|
||||
/// File and duration are set via dc_msg_set_file(), dc_msg_set_duration()
|
||||
/// and retrieved via dc_msg_get_file(), dc_msg_get_duration()
|
||||
Voice = 41,
|
||||
|
||||
/// Video messages.
|
||||
/// File, width, height and durarion
|
||||
/// are set via dc_msg_set_file(), dc_msg_set_dimension(), dc_msg_set_duration()
|
||||
/// and retrieved via
|
||||
/// dc_msg_get_file(), dc_msg_get_width(),
|
||||
/// dc_msg_get_height(), dc_msg_get_duration().
|
||||
Video = 50,
|
||||
|
||||
/// Message containing any file, eg. a PDF.
|
||||
/// The file is set via dc_msg_set_file()
|
||||
/// and retrieved via dc_msg_get_file().
|
||||
File = 60,
|
||||
}
|
||||
|
||||
impl ToSql for Viewtype {
|
||||
fn to_sql(&self) -> sql::Result<ToSqlOutput> {
|
||||
let num: i64 = self
|
||||
.to_i64()
|
||||
.expect("impossible: Viewtype -> i64 conversion failed");
|
||||
|
||||
Ok(ToSqlOutput::Owned(Value::Integer(num)))
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSql for Viewtype {
|
||||
fn column_result(col: ValueRef) -> FromSqlResult<Self> {
|
||||
let inner = FromSql::column_result(col)?;
|
||||
FromPrimitive::from_i64(inner).ok_or(FromSqlError::InvalidType)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Viewtype {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
self.to_i64()
|
||||
.expect("impossible: Viewtype -> i64 conversion failed")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// These constants are used as events
|
||||
// reported to the callback given to dc_context_new().
|
||||
// If you do not want to handle an event, it is always safe to return 0,
|
||||
|
||||
@@ -371,14 +371,14 @@ pub unsafe fn dc_prepare_msg<'a>(
|
||||
return msg_id;
|
||||
}
|
||||
|
||||
pub fn msgtype_has_file(msgtype: i32) -> bool {
|
||||
pub fn msgtype_has_file(msgtype: Viewtype) -> bool {
|
||||
match msgtype {
|
||||
DC_MSG_IMAGE => true,
|
||||
DC_MSG_GIF => true,
|
||||
DC_MSG_AUDIO => true,
|
||||
DC_MSG_VOICE => true,
|
||||
DC_MSG_VIDEO => true,
|
||||
DC_MSG_FILE => true,
|
||||
Viewtype::Image => true,
|
||||
Viewtype::Gif => true,
|
||||
Viewtype::Audio => true,
|
||||
Viewtype::Voice => true,
|
||||
Viewtype::Video => true,
|
||||
Viewtype::File => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -392,7 +392,7 @@ unsafe fn prepare_msg_common<'a>(
|
||||
let mut OK_TO_CONTINUE = true;
|
||||
(*msg).id = 0i32 as uint32_t;
|
||||
(*msg).context = context;
|
||||
if (*msg).type_0 == DC_MSG_TEXT {
|
||||
if (*msg).type_0 == Viewtype::Text {
|
||||
/* the caller should check if the message text is empty */
|
||||
} else if msgtype_has_file((*msg).type_0) {
|
||||
let mut pathNfilename = (*msg)
|
||||
@@ -417,16 +417,16 @@ unsafe fn prepare_msg_common<'a>(
|
||||
OK_TO_CONTINUE = false;
|
||||
} else {
|
||||
(*msg).param.set(Param::File, as_str(pathNfilename));
|
||||
if (*msg).type_0 == DC_MSG_FILE || (*msg).type_0 == DC_MSG_IMAGE {
|
||||
if (*msg).type_0 == Viewtype::File || (*msg).type_0 == Viewtype::Image {
|
||||
/* Correct the type, take care not to correct already very special formats as GIF or VOICE.
|
||||
Typical conversions:
|
||||
- from FILE to AUDIO/VIDEO/IMAGE
|
||||
- from FILE/IMAGE to GIF */
|
||||
let mut better_type = 0;
|
||||
let mut better_type = Viewtype::Unknown;
|
||||
let mut better_mime = std::ptr::null_mut();
|
||||
|
||||
dc_msg_guess_msgtype_from_suffix(pathNfilename, &mut better_type, &mut better_mime);
|
||||
if 0 != better_type && !better_mime.is_null() {
|
||||
if Viewtype::Unknown != better_type && !better_mime.is_null() {
|
||||
(*msg).type_0 = better_type;
|
||||
(*msg).param.set(Param::MimeType, as_str(better_mime));
|
||||
}
|
||||
@@ -436,7 +436,7 @@ unsafe fn prepare_msg_common<'a>(
|
||||
|
||||
dc_msg_guess_msgtype_from_suffix(
|
||||
pathNfilename,
|
||||
0 as *mut libc::c_int,
|
||||
0 as *mut Viewtype,
|
||||
&mut better_mime,
|
||||
);
|
||||
|
||||
@@ -974,7 +974,7 @@ pub unsafe fn dc_send_text_msg(
|
||||
return 0;
|
||||
}
|
||||
|
||||
let mut msg = dc_msg_new(context, 10);
|
||||
let mut msg = dc_msg_new(context, Viewtype::Text);
|
||||
(*msg).text = dc_strdup(text_to_send);
|
||||
let ret = dc_send_msg(context, chat_id, msg);
|
||||
dc_msg_unref(msg);
|
||||
@@ -1004,7 +1004,7 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t
|
||||
}
|
||||
// save new draft
|
||||
if !msg.is_null() {
|
||||
if (*msg).type_0 == DC_MSG_TEXT {
|
||||
if (*msg).type_0 == Viewtype::Text {
|
||||
if (*msg).text.is_null() || *(*msg).text.offset(0isize) as libc::c_int == 0i32 {
|
||||
OK_TO_CONTINUE = false;
|
||||
}
|
||||
@@ -1258,20 +1258,20 @@ pub fn dc_marknoticed_all_chats(context: &Context) -> bool {
|
||||
pub fn dc_get_chat_media(
|
||||
context: &Context,
|
||||
chat_id: uint32_t,
|
||||
msg_type: libc::c_int,
|
||||
msg_type2: libc::c_int,
|
||||
msg_type3: libc::c_int,
|
||||
msg_type: Viewtype,
|
||||
msg_type2: Viewtype,
|
||||
msg_type3: Viewtype,
|
||||
) -> *mut dc_array_t {
|
||||
context.sql.query_map(
|
||||
"SELECT id FROM msgs WHERE chat_id=? AND (type=? OR type=? OR type=?) ORDER BY timestamp, id;",
|
||||
params![
|
||||
chat_id as i32,
|
||||
msg_type,
|
||||
if msg_type2 > 0 {
|
||||
if msg_type2 != Viewtype::Unknown {
|
||||
msg_type2
|
||||
} else {
|
||||
msg_type
|
||||
}, if msg_type3 > 0 {
|
||||
}, if msg_type3 != Viewtype::Unknown {
|
||||
msg_type3
|
||||
} else {
|
||||
msg_type
|
||||
@@ -1292,9 +1292,9 @@ pub unsafe fn dc_get_next_media(
|
||||
context: &Context,
|
||||
curr_msg_id: uint32_t,
|
||||
dir: libc::c_int,
|
||||
msg_type: libc::c_int,
|
||||
msg_type2: libc::c_int,
|
||||
msg_type3: libc::c_int,
|
||||
msg_type: Viewtype,
|
||||
msg_type2: Viewtype,
|
||||
msg_type3: Viewtype,
|
||||
) -> uint32_t {
|
||||
let mut ret_msg_id: uint32_t = 0i32 as uint32_t;
|
||||
let msg: *mut dc_msg_t = dc_msg_new_untyped(context);
|
||||
@@ -1306,7 +1306,7 @@ pub unsafe fn dc_get_next_media(
|
||||
list = dc_get_chat_media(
|
||||
context,
|
||||
(*msg).chat_id,
|
||||
if msg_type > 0i32 {
|
||||
if msg_type != Viewtype::Unknown {
|
||||
msg_type
|
||||
} else {
|
||||
(*msg).type_0
|
||||
@@ -1510,7 +1510,7 @@ pub unsafe fn dc_create_group_chat(
|
||||
chat_id = sql::get_rowid(context, &context.sql, "chats", "grpid", grpid);
|
||||
if chat_id != 0 {
|
||||
if 0 != dc_add_to_chat_contacts_table(context, chat_id, 1) {
|
||||
let draft_msg = dc_msg_new(context, 10);
|
||||
let draft_msg = dc_msg_new(context, Viewtype::Text);
|
||||
dc_msg_set_text(draft_msg, draft_txt.as_ptr());
|
||||
set_draft_raw(context, chat_id, draft_msg);
|
||||
dc_msg_unref(draft_msg);
|
||||
@@ -1619,7 +1619,7 @@ pub unsafe fn dc_add_contact_to_chat_ex(
|
||||
}
|
||||
if OK_TO_CONTINUE {
|
||||
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
||||
(*msg).type_0 = DC_MSG_TEXT;
|
||||
(*msg).type_0 = Viewtype::Text;
|
||||
(*msg).text = to_cstring(context.stock_system_msg(
|
||||
StockMessage::MsgAddMember,
|
||||
as_str((*contact).addr),
|
||||
@@ -1730,7 +1730,7 @@ pub unsafe fn dc_remove_contact_from_chat(
|
||||
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
|
||||
if !contact.is_null() {
|
||||
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
||||
(*msg).type_0 = DC_MSG_TEXT;
|
||||
(*msg).type_0 = Viewtype::Text;
|
||||
if (*contact).id == 1 as libc::c_uint {
|
||||
dc_set_group_explicitly_left(context, (*chat).grpid);
|
||||
(*msg).text = to_cstring(context.stock_system_msg(
|
||||
@@ -1845,7 +1845,7 @@ pub unsafe fn dc_set_chat_name(
|
||||
.is_ok()
|
||||
{
|
||||
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
||||
(*msg).type_0 = DC_MSG_TEXT;
|
||||
(*msg).type_0 = Viewtype::Text;
|
||||
(*msg).text = to_cstring(context.stock_system_msg(
|
||||
StockMessage::MsgGrpName,
|
||||
as_str((*chat).name),
|
||||
@@ -1917,7 +1917,7 @@ pub unsafe fn dc_set_chat_profile_image(
|
||||
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
||||
(*msg).param.set_int(Param::Cmd, 3);
|
||||
(*msg).param.set(Param::Arg, as_str(new_image_rel));
|
||||
(*msg).type_0 = DC_MSG_TEXT;
|
||||
(*msg).type_0 = Viewtype::Text;
|
||||
(*msg).text = to_cstring(context.stock_system_msg(
|
||||
if !new_image_rel.is_null() {
|
||||
StockMessage::MsgGrpImgChanged
|
||||
@@ -2287,7 +2287,7 @@ pub fn dc_add_device_msg(context: &Context, chat_id: uint32_t, text: *const libc
|
||||
2,
|
||||
2,
|
||||
unsafe {dc_create_smeared_timestamp(context)},
|
||||
DC_MSG_TEXT,
|
||||
Viewtype::Text,
|
||||
DC_STATE_IN_NOTICED,
|
||||
as_str(text),
|
||||
as_str(rfc724_mid),
|
||||
|
||||
@@ -139,7 +139,7 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char {
|
||||
let chat_id = dc_create_chat_by_contact_id(context, 1i32 as uint32_t);
|
||||
if !(chat_id == 0i32 as libc::c_uint) {
|
||||
msg = dc_msg_new_untyped(context);
|
||||
(*msg).type_0 = DC_MSG_FILE;
|
||||
(*msg).type_0 = Viewtype::File;
|
||||
(*msg).param.set(Param::File, as_str(setup_file_name));
|
||||
|
||||
(*msg)
|
||||
|
||||
@@ -1184,8 +1184,8 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
if strlen(pathNfilename) > 0 {
|
||||
if ((*mimefactory.msg).type_0 == DC_MSG_IMAGE
|
||||
|| (*mimefactory.msg).type_0 == DC_MSG_GIF)
|
||||
if ((*mimefactory.msg).type_0 == Viewtype::Image
|
||||
|| (*mimefactory.msg).type_0 == Viewtype::Gif)
|
||||
&& !(*mimefactory.msg).param.exists(Param::Width)
|
||||
{
|
||||
let mut buf = 0 as *mut libc::c_uchar;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::ffi::CString;
|
||||
|
||||
use crate::constants::Event;
|
||||
use crate::constants::*;
|
||||
use crate::context::*;
|
||||
use crate::dc_array::*;
|
||||
use crate::dc_chat::*;
|
||||
@@ -98,7 +99,7 @@ pub unsafe fn dc_send_locations_to_chat(
|
||||
.is_ok()
|
||||
{
|
||||
if 0 != seconds && !is_sending_locations_before {
|
||||
msg = dc_msg_new(context, 10i32);
|
||||
msg = dc_msg_new(context, Viewtype::Text);
|
||||
(*msg).text = to_cstring(context.stock_system_msg(
|
||||
StockMessage::MsgLocationEnabled,
|
||||
"",
|
||||
@@ -702,7 +703,7 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu
|
||||
// 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
|
||||
// and dc_set_location() is typically called periodically, this is ok)
|
||||
let mut msg = dc_msg_new(context, 10);
|
||||
let mut msg = dc_msg_new(context, Viewtype::Text);
|
||||
(*msg).hidden = 1;
|
||||
(*msg).param.set_int(Param::Cmd, 9);
|
||||
dc_send_msg(context, chat_id as u32, msg);
|
||||
|
||||
@@ -738,10 +738,9 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(grpimage) = grpimage {
|
||||
let mut meta = dc_msg_new_untyped((*factory).context);
|
||||
(*meta).type_0 = DC_MSG_IMAGE as libc::c_int;
|
||||
(*meta).type_0 = Viewtype::Image;
|
||||
(*meta).param.set(Param::File, grpimage);
|
||||
|
||||
let mut filename_as_sent = 0 as *mut libc::c_char;
|
||||
@@ -762,11 +761,11 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
|
||||
dc_msg_unref(meta);
|
||||
}
|
||||
|
||||
if (*msg).type_0 == DC_MSG_VOICE
|
||||
|| (*msg).type_0 == DC_MSG_AUDIO
|
||||
|| (*msg).type_0 == DC_MSG_VIDEO
|
||||
if (*msg).type_0 == Viewtype::Voice
|
||||
|| (*msg).type_0 == Viewtype::Audio
|
||||
|| (*msg).type_0 == Viewtype::Video
|
||||
{
|
||||
if (*msg).type_0 == DC_MSG_VOICE {
|
||||
if (*msg).type_0 == Viewtype::Voice {
|
||||
mailimf_fields_add(
|
||||
imf_fields,
|
||||
mailimf_field_new_custom(
|
||||
@@ -1179,7 +1178,7 @@ unsafe fn build_body_file(
|
||||
let mut filename_encoded = 0 as *mut libc::c_char;
|
||||
|
||||
if !pathNfilename.is_null() {
|
||||
if (*msg).type_0 == DC_MSG_VOICE {
|
||||
if (*msg).type_0 == Viewtype::Voice {
|
||||
let ts = chrono::Utc.timestamp((*msg).timestamp_sort as i64, 0);
|
||||
|
||||
let suffix = if !suffix.is_null() {
|
||||
@@ -1191,9 +1190,9 @@ unsafe fn build_body_file(
|
||||
.format(&format!("voice-message_%Y-%m-%d_%H-%M-%S.{}", suffix))
|
||||
.to_string();
|
||||
filename_to_send = to_cstring(res);
|
||||
} else if (*msg).type_0 == DC_MSG_AUDIO {
|
||||
} else if (*msg).type_0 == Viewtype::Audio {
|
||||
filename_to_send = dc_get_filename(pathNfilename)
|
||||
} else if (*msg).type_0 == DC_MSG_IMAGE || (*msg).type_0 == DC_MSG_GIF {
|
||||
} else if (*msg).type_0 == Viewtype::Image || (*msg).type_0 == Viewtype::Gif {
|
||||
if base_name.is_null() {
|
||||
base_name = b"image\x00" as *const u8 as *const libc::c_char
|
||||
}
|
||||
@@ -1206,7 +1205,7 @@ unsafe fn build_body_file(
|
||||
b"dat\x00" as *const u8 as *const libc::c_char
|
||||
},
|
||||
)
|
||||
} else if (*msg).type_0 == DC_MSG_VIDEO {
|
||||
} else if (*msg).type_0 == Viewtype::Video {
|
||||
filename_to_send = dc_mprintf(
|
||||
b"video.%s\x00" as *const u8 as *const libc::c_char,
|
||||
if !suffix.is_null() {
|
||||
|
||||
@@ -25,7 +25,7 @@ pub struct dc_msg_t<'a> {
|
||||
pub to_id: uint32_t,
|
||||
pub chat_id: uint32_t,
|
||||
pub move_state: dc_move_state_t,
|
||||
pub type_0: libc::c_int,
|
||||
pub type_0: Viewtype,
|
||||
pub state: libc::c_int,
|
||||
pub hidden: libc::c_int,
|
||||
pub timestamp_sort: i64,
|
||||
@@ -177,15 +177,15 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
|
||||
}
|
||||
free(p as *mut libc::c_void);
|
||||
|
||||
if (*msg).type_0 != DC_MSG_TEXT {
|
||||
if (*msg).type_0 != Viewtype::Text {
|
||||
ret += "Type: ";
|
||||
match (*msg).type_0 {
|
||||
DC_MSG_AUDIO => ret += "Audio",
|
||||
DC_MSG_FILE => ret += "File",
|
||||
DC_MSG_GIF => ret += "GIF",
|
||||
DC_MSG_IMAGE => ret += "Image",
|
||||
DC_MSG_VIDEO => ret += "Video",
|
||||
DC_MSG_VOICE => ret += "Voice",
|
||||
Viewtype::Audio => ret += "Audio",
|
||||
Viewtype::File => ret += "File",
|
||||
Viewtype::Gif => ret += "GIF",
|
||||
Viewtype::Image => ret += "Image",
|
||||
Viewtype::Video => ret += "Video",
|
||||
Viewtype::Voice => ret += "Voice",
|
||||
_ => ret += &format!("{}", (*msg).type_0),
|
||||
}
|
||||
ret += "\n";
|
||||
@@ -222,7 +222,7 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
|
||||
}
|
||||
|
||||
pub unsafe fn dc_msg_new_untyped<'a>(context: &'a Context) -> *mut dc_msg_t<'a> {
|
||||
dc_msg_new(context, 0i32)
|
||||
dc_msg_new(context, Viewtype::Unknown)
|
||||
}
|
||||
|
||||
/* *
|
||||
@@ -235,7 +235,7 @@ pub unsafe fn dc_msg_new_untyped<'a>(context: &'a Context) -> *mut dc_msg_t<'a>
|
||||
// to check if a mail was sent, use dc_msg_is_sent()
|
||||
// approx. max. length returned by dc_msg_get_text()
|
||||
// approx. max. length returned by dc_get_msg_info()
|
||||
pub unsafe fn dc_msg_new<'a>(context: &'a Context, viewtype: libc::c_int) -> *mut dc_msg_t<'a> {
|
||||
pub unsafe fn dc_msg_new<'a>(context: &'a Context, viewtype: Viewtype) -> *mut dc_msg_t<'a> {
|
||||
let msg = dc_msg_t {
|
||||
magic: 0x11561156,
|
||||
id: 0,
|
||||
@@ -301,7 +301,7 @@ pub unsafe fn dc_msg_get_filemime(msg: *const dc_msg_t) -> *mut libc::c_char {
|
||||
None => {
|
||||
if let Some(file) = (*msg).param.get(Param::File) {
|
||||
let file_c = to_cstring(file);
|
||||
dc_msg_guess_msgtype_from_suffix(file_c, 0 as *mut libc::c_int, &mut ret);
|
||||
dc_msg_guess_msgtype_from_suffix(file_c, 0 as *mut Viewtype, &mut ret);
|
||||
if ret.is_null() {
|
||||
ret = dc_strdup(
|
||||
b"application/octet-stream\x00" as *const u8 as *const libc::c_char,
|
||||
@@ -323,11 +323,11 @@ pub unsafe fn dc_msg_get_filemime(msg: *const dc_msg_t) -> *mut libc::c_char {
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe fn dc_msg_guess_msgtype_from_suffix(
|
||||
pathNfilename: *const libc::c_char,
|
||||
mut ret_msgtype: *mut libc::c_int,
|
||||
mut ret_msgtype: *mut Viewtype,
|
||||
mut ret_mime: *mut *mut libc::c_char,
|
||||
) {
|
||||
let mut suffix: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
let mut dummy_msgtype: libc::c_int = 0;
|
||||
let mut dummy_msgtype = Viewtype::Unknown;
|
||||
let mut dummy_buf: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
if !pathNfilename.is_null() {
|
||||
if ret_msgtype.is_null() {
|
||||
@@ -336,37 +336,37 @@ pub unsafe fn dc_msg_guess_msgtype_from_suffix(
|
||||
if ret_mime.is_null() {
|
||||
ret_mime = &mut dummy_buf
|
||||
}
|
||||
*ret_msgtype = 0;
|
||||
*ret_msgtype = Viewtype::Unknown;
|
||||
*ret_mime = 0 as *mut libc::c_char;
|
||||
suffix = dc_get_filesuffix_lc(pathNfilename);
|
||||
if !suffix.is_null() {
|
||||
if strcmp(suffix, b"mp3\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||
*ret_msgtype = DC_MSG_AUDIO;
|
||||
*ret_msgtype = Viewtype::Audio;
|
||||
*ret_mime = dc_strdup(b"audio/mpeg\x00" as *const u8 as *const libc::c_char)
|
||||
} else if strcmp(suffix, b"aac\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||
*ret_msgtype = DC_MSG_AUDIO;
|
||||
*ret_msgtype = Viewtype::Audio;
|
||||
*ret_mime = dc_strdup(b"audio/aac\x00" as *const u8 as *const libc::c_char)
|
||||
} else if strcmp(suffix, b"mp4\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||
*ret_msgtype = DC_MSG_VIDEO;
|
||||
*ret_msgtype = Viewtype::Video;
|
||||
*ret_mime = dc_strdup(b"video/mp4\x00" as *const u8 as *const libc::c_char)
|
||||
} else if strcmp(suffix, b"jpg\x00" as *const u8 as *const libc::c_char) == 0i32
|
||||
|| strcmp(suffix, b"jpeg\x00" as *const u8 as *const libc::c_char) == 0i32
|
||||
{
|
||||
*ret_msgtype = DC_MSG_IMAGE;
|
||||
*ret_msgtype = Viewtype::Image;
|
||||
*ret_mime = dc_strdup(b"image/jpeg\x00" as *const u8 as *const libc::c_char)
|
||||
} else if strcmp(suffix, b"png\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||
*ret_msgtype = DC_MSG_IMAGE;
|
||||
*ret_msgtype = Viewtype::Image;
|
||||
*ret_mime = dc_strdup(b"image/png\x00" as *const u8 as *const libc::c_char)
|
||||
} else if strcmp(suffix, b"webp\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||
*ret_msgtype = DC_MSG_IMAGE;
|
||||
*ret_msgtype = Viewtype::Image;
|
||||
*ret_mime = dc_strdup(b"image/webp\x00" as *const u8 as *const libc::c_char)
|
||||
} else if strcmp(suffix, b"gif\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||
*ret_msgtype = DC_MSG_GIF;
|
||||
*ret_msgtype = Viewtype::Gif;
|
||||
*ret_mime = dc_strdup(b"image/gif\x00" as *const u8 as *const libc::c_char)
|
||||
} else if strcmp(suffix, b"vcf\x00" as *const u8 as *const libc::c_char) == 0i32
|
||||
|| strcmp(suffix, b"vcard\x00" as *const u8 as *const libc::c_char) == 0i32
|
||||
{
|
||||
*ret_msgtype = DC_MSG_FILE;
|
||||
*ret_msgtype = Viewtype::File;
|
||||
*ret_mime = dc_strdup(b"text/vcard\x00" as *const u8 as *const libc::c_char)
|
||||
}
|
||||
}
|
||||
@@ -681,9 +681,9 @@ pub unsafe fn dc_msg_get_chat_id(msg: *const dc_msg_t) -> uint32_t {
|
||||
};
|
||||
}
|
||||
|
||||
pub unsafe fn dc_msg_get_viewtype(msg: *const dc_msg_t) -> libc::c_int {
|
||||
pub unsafe fn dc_msg_get_viewtype(msg: *const dc_msg_t) -> Viewtype {
|
||||
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
|
||||
return 0i32;
|
||||
return Viewtype::Unknown;
|
||||
}
|
||||
|
||||
(*msg).type_0
|
||||
@@ -853,7 +853,7 @@ pub unsafe fn dc_msg_get_summarytext(
|
||||
/* the returned value must be free()'d */
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe fn dc_msg_get_summarytext_by_raw(
|
||||
type_0: libc::c_int,
|
||||
type_0: Viewtype,
|
||||
text: *const libc::c_char,
|
||||
param: &mut Params,
|
||||
approx_characters: libc::c_int,
|
||||
@@ -866,11 +866,11 @@ pub unsafe fn dc_msg_get_summarytext_by_raw(
|
||||
let mut value: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
let mut append_text: libc::c_int = 1i32;
|
||||
match type_0 {
|
||||
20 => prefix = to_cstring(context.stock_str(StockMessage::Image)),
|
||||
21 => prefix = to_cstring(context.stock_str(StockMessage::Gif)),
|
||||
50 => prefix = to_cstring(context.stock_str(StockMessage::Video)),
|
||||
41 => prefix = to_cstring(context.stock_str(StockMessage::VoiceMessage)),
|
||||
40 | 60 => {
|
||||
Viewtype::Image => prefix = to_cstring(context.stock_str(StockMessage::Image)),
|
||||
Viewtype::Gif => prefix = to_cstring(context.stock_str(StockMessage::Gif)),
|
||||
Viewtype::Video => prefix = to_cstring(context.stock_str(StockMessage::Video)),
|
||||
Viewtype::Voice => prefix = to_cstring(context.stock_str(StockMessage::VoiceMessage)),
|
||||
Viewtype::Audio | Viewtype::File => {
|
||||
if param.get_int(Param::Cmd) == Some(6) {
|
||||
prefix = to_cstring(context.stock_str(StockMessage::AcSetupMsgSubject));
|
||||
append_text = 0i32
|
||||
@@ -879,7 +879,7 @@ pub unsafe fn dc_msg_get_summarytext_by_raw(
|
||||
value = dc_get_filename(pathNfilename);
|
||||
let label = CString::new(
|
||||
context
|
||||
.stock_str(if type_0 == DC_MSG_AUDIO {
|
||||
.stock_str(if type_0 == Viewtype::Audio {
|
||||
StockMessage::Audio
|
||||
} else {
|
||||
StockMessage::File
|
||||
@@ -1000,7 +1000,7 @@ pub unsafe fn dc_msg_is_increation(msg: *const dc_msg_t) -> libc::c_int {
|
||||
pub unsafe fn dc_msg_is_setupmessage(msg: *const dc_msg_t) -> bool {
|
||||
if msg.is_null()
|
||||
|| (*msg).magic != 0x11561156i32 as libc::c_uint
|
||||
|| (*msg).type_0 != DC_MSG_FILE as libc::c_int
|
||||
|| (*msg).type_0 != Viewtype::File
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1442,7 +1442,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_dc_msg_guess_msgtype_from_suffix() {
|
||||
unsafe {
|
||||
let mut type_0: libc::c_int = 0;
|
||||
let mut type_0 = Viewtype::Unknown;
|
||||
let mut mime_0: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
|
||||
dc_msg_guess_msgtype_from_suffix(
|
||||
@@ -1450,7 +1450,7 @@ mod tests {
|
||||
&mut type_0,
|
||||
&mut mime_0,
|
||||
);
|
||||
assert_eq!(type_0, DC_MSG_AUDIO as libc::c_int);
|
||||
assert_eq!(type_0, Viewtype::Audio);
|
||||
assert_eq!(as_str(mime_0 as *const libc::c_char), "audio/mpeg");
|
||||
free(mime_0 as *mut libc::c_void);
|
||||
|
||||
@@ -1459,7 +1459,7 @@ mod tests {
|
||||
&mut type_0,
|
||||
&mut mime_0,
|
||||
);
|
||||
assert_eq!(type_0, DC_MSG_AUDIO as libc::c_int);
|
||||
assert_eq!(type_0, Viewtype::Audio);
|
||||
assert_eq!(as_str(mime_0 as *const libc::c_char), "audio/aac");
|
||||
free(mime_0 as *mut libc::c_void);
|
||||
|
||||
@@ -1468,7 +1468,7 @@ mod tests {
|
||||
&mut type_0,
|
||||
&mut mime_0,
|
||||
);
|
||||
assert_eq!(type_0, DC_MSG_VIDEO as libc::c_int);
|
||||
assert_eq!(type_0, Viewtype::Video);
|
||||
assert_eq!(as_str(mime_0 as *const libc::c_char), "video/mp4");
|
||||
free(mime_0 as *mut libc::c_void);
|
||||
|
||||
@@ -1477,7 +1477,7 @@ mod tests {
|
||||
&mut type_0,
|
||||
&mut mime_0,
|
||||
);
|
||||
assert_eq!(type_0, DC_MSG_IMAGE as libc::c_int);
|
||||
assert_eq!(type_0, Viewtype::Image);
|
||||
assert_eq!(
|
||||
CStr::from_ptr(mime_0 as *const libc::c_char)
|
||||
.to_str()
|
||||
@@ -1491,7 +1491,7 @@ mod tests {
|
||||
&mut type_0,
|
||||
&mut mime_0,
|
||||
);
|
||||
assert_eq!(type_0, DC_MSG_IMAGE as libc::c_int);
|
||||
assert_eq!(type_0, Viewtype::Image);
|
||||
assert_eq!(
|
||||
CStr::from_ptr(mime_0 as *const libc::c_char)
|
||||
.to_str()
|
||||
@@ -1505,7 +1505,7 @@ mod tests {
|
||||
&mut type_0,
|
||||
&mut mime_0,
|
||||
);
|
||||
assert_eq!(type_0, DC_MSG_IMAGE as libc::c_int);
|
||||
assert_eq!(type_0, Viewtype::Image);
|
||||
assert_eq!(
|
||||
CStr::from_ptr(mime_0 as *const libc::c_char)
|
||||
.to_str()
|
||||
@@ -1519,7 +1519,7 @@ mod tests {
|
||||
&mut type_0,
|
||||
&mut mime_0,
|
||||
);
|
||||
assert_eq!(type_0, DC_MSG_IMAGE as libc::c_int);
|
||||
assert_eq!(type_0, Viewtype::Image);
|
||||
assert_eq!(
|
||||
CStr::from_ptr(mime_0 as *const libc::c_char)
|
||||
.to_str()
|
||||
@@ -1533,7 +1533,7 @@ mod tests {
|
||||
&mut type_0,
|
||||
&mut mime_0,
|
||||
);
|
||||
assert_eq!(type_0, DC_MSG_GIF as libc::c_int);
|
||||
assert_eq!(type_0, Viewtype::Gif);
|
||||
assert_eq!(
|
||||
CStr::from_ptr(mime_0 as *const libc::c_char)
|
||||
.to_str()
|
||||
@@ -1547,7 +1547,7 @@ mod tests {
|
||||
&mut type_0,
|
||||
&mut mime_0,
|
||||
);
|
||||
assert_eq!(type_0, DC_MSG_FILE as libc::c_int);
|
||||
assert_eq!(type_0, Viewtype::File);
|
||||
assert_eq!(
|
||||
CStr::from_ptr(mime_0 as *const libc::c_char)
|
||||
.to_str()
|
||||
|
||||
@@ -263,7 +263,7 @@ unsafe fn send_handshake_msg(
|
||||
grpid: *const libc::c_char,
|
||||
) {
|
||||
let mut msg: *mut dc_msg_t = dc_msg_new_untyped(context);
|
||||
(*msg).type_0 = DC_MSG_TEXT;
|
||||
(*msg).type_0 = Viewtype::Text;
|
||||
(*msg).text = dc_mprintf(
|
||||
b"Secure-Join: %s\x00" as *const u8 as *const libc::c_char,
|
||||
step,
|
||||
|
||||
Reference in New Issue
Block a user