Store dc_mimeparser_t::parts as Vec instead of carray

This commit is contained in:
Alexander Krotov
2019-08-01 00:32:57 +03:00
parent b6b0849bce
commit a4f94dbf86
3 changed files with 124 additions and 176 deletions

View File

@@ -44,7 +44,7 @@ pub struct dc_mimepart_t {
#[derive(Clone)]
#[allow(non_camel_case_types)]
pub struct dc_mimeparser_t<'a> {
pub parts: *mut carray,
pub parts: Vec<dc_mimepart_t>,
pub mimeroot: *mut mailmime,
pub header: HashMap<String, *mut mailimf_field>,
pub header_root: *mut mailimf_fields,
@@ -71,7 +71,7 @@ static mut S_GENERATE_COMPOUND_MSGS: libc::c_int = 1i32;
pub unsafe fn dc_mimeparser_new(context: &Context) -> dc_mimeparser_t {
dc_mimeparser_t {
parts: carray_new(16i32 as libc::c_uint),
parts: Vec::new(),
mimeroot: std::ptr::null_mut(),
header: Default::default(),
header_root: std::ptr::null_mut(),
@@ -91,25 +91,13 @@ pub unsafe fn dc_mimeparser_new(context: &Context) -> dc_mimeparser_t {
pub unsafe fn dc_mimeparser_unref(mimeparser: &mut dc_mimeparser_t) {
dc_mimeparser_empty(mimeparser);
if !(*mimeparser).parts.is_null() {
carray_free((*mimeparser).parts);
}
}
pub unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) {
if !(*mimeparser).parts.is_null() {
let mut i: libc::c_int;
let cnt: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int;
i = 0i32;
while i < cnt {
let part = carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
if !part.is_null() {
dc_mimepart_unref(*Box::from_raw(part));
}
i += 1
}
carray_set_size((*mimeparser).parts, 0i32 as libc::c_uint);
for part in mimeparser.parts.drain(..) {
dc_mimepart_unref(part);
}
assert!(mimeparser.parts.is_empty());
(*mimeparser).header_root = 0 as *mut mailimf_fields;
(*mimeparser).header.clear();
if !(*mimeparser).header_protected.is_null() {
@@ -183,29 +171,34 @@ pub unsafe fn dc_mimeparser_parse(
(*mimeparser).is_send_by_messenger = 1i32
}
if !dc_mimeparser_lookup_field(mimeparser, "Autocrypt-Setup-Message").is_null() {
let mut i: libc::c_int;
let mut has_setup_file: libc::c_int = 0i32;
i = 0i32;
while (i as libc::c_uint) < carray_count((*mimeparser).parts) {
let part: *mut dc_mimepart_t =
carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
if (*part).int_mimetype == 111i32 {
for part in &mimeparser.parts {
if part.int_mimetype == 111i32 {
has_setup_file = 1i32
}
i += 1
}
if 0 != has_setup_file {
(*mimeparser).is_system_message = 6i32;
i = 0i32;
while (i as libc::c_uint) < carray_count((*mimeparser).parts) {
let part_0 =
carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
if (*part_0).int_mimetype != 111i32 {
dc_mimepart_unref(*Box::from_raw(part_0));
carray_delete_slow((*mimeparser).parts, i as libc::c_uint);
i -= 1
mimeparser.is_system_message = 6i32;
// TODO: replace the following code with this
// once drain_filter stabilizes.
//
// See https://doc.rust-lang.org/std/vec/struct.Vec.html#method.drain_filter
// and https://github.com/rust-lang/rust/issues/43244
//
// mimeparser
// .parts
// .drain_filter(|part| part.int_mimetype != 111)
// .for_each(|part| dc_mimepart_unref(part));
let mut i = 0;
while i != mimeparser.parts.len() {
if mimeparser.parts[i].int_mimetype != 111 {
let part = mimeparser.parts.remove(i);
dc_mimepart_unref(part);
} else {
i += 1;
}
i += 1
}
}
} else {
@@ -224,40 +217,42 @@ pub unsafe fn dc_mimeparser_parse(
}
}
if !dc_mimeparser_lookup_field(mimeparser, "Chat-Group-Image").is_null()
&& carray_count((*mimeparser).parts) >= 1i32 as libc::c_uint
&& !mimeparser.parts.is_empty()
{
let textpart: *mut dc_mimepart_t =
carray_get((*mimeparser).parts, 0i32 as libc::c_uint) as *mut dc_mimepart_t;
if (*textpart).type_0 == 10i32 {
if carray_count((*mimeparser).parts) >= 2i32 as libc::c_uint {
let mut imgpart: *mut dc_mimepart_t =
carray_get((*mimeparser).parts, 1i32 as libc::c_uint) as *mut dc_mimepart_t;
if (*imgpart).type_0 == 20i32 {
(*imgpart).is_meta = 1i32
let textpart = &mimeparser.parts[0];
if textpart.type_0 == 10i32 {
if mimeparser.parts.len() >= 2 {
let imgpart = &mut mimeparser.parts[1];
if imgpart.type_0 == 20i32 {
imgpart.is_meta = 1i32
}
}
}
}
if 0 != (*mimeparser).is_send_by_messenger
&& 0 != S_GENERATE_COMPOUND_MSGS
&& carray_count((*mimeparser).parts) == 2i32 as libc::c_uint
&& mimeparser.parts.len() == 2
{
let mut textpart_0 = carray_get((*mimeparser).parts, 0) as *mut dc_mimepart_t;
let mut filepart = carray_get((*mimeparser).parts, 1) as *mut dc_mimepart_t;
if (*textpart_0).type_0 == 10i32
&& ((*filepart).type_0 == 20i32
|| (*filepart).type_0 == 21i32
|| (*filepart).type_0 == 40i32
|| (*filepart).type_0 == 41i32
|| (*filepart).type_0 == 50i32
|| (*filepart).type_0 == 60i32)
&& 0 == (*filepart).is_meta
let need_drop: bool;
{
free((*filepart).msg as *mut libc::c_void);
(*filepart).msg = (*textpart_0).msg;
(*textpart_0).msg = 0 as *mut libc::c_char;
dc_mimepart_unref(*Box::from_raw(textpart_0));
carray_delete_slow((*mimeparser).parts, 0i32 as libc::c_uint);
let textpart = &mimeparser.parts[0];
let filepart = &mimeparser.parts[1];
need_drop = textpart.type_0 == 10i32
&& (filepart.type_0 == 20i32
|| filepart.type_0 == 21i32
|| filepart.type_0 == 40i32
|| filepart.type_0 == 41i32
|| filepart.type_0 == 50i32
|| filepart.type_0 == 60i32)
&& 0 == filepart.is_meta;
}
if need_drop {
free(mimeparser.parts[1].msg as *mut libc::c_void);
let mut textpart = mimeparser.parts.swap_remove(0);
mimeparser.parts[1].msg = textpart.msg;
textpart.msg = 0 as *mut libc::c_char;
dc_mimepart_unref(textpart);
}
}
if !(*mimeparser).subject.is_null() {
@@ -284,24 +279,16 @@ pub unsafe fn dc_mimeparser_parse(
}
dc_trim(subj);
if 0 != *subj.offset(0isize) {
let mut i_0: libc::c_int;
let icnt: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int;
i_0 = 0i32;
while i_0 < icnt {
let mut part_1: *mut dc_mimepart_t =
carray_get((*mimeparser).parts, i_0 as libc::c_uint)
as *mut dc_mimepart_t;
if (*part_1).type_0 == 10i32 {
for part in mimeparser.parts.iter_mut() {
if part.type_0 == 10i32 {
let new_txt: *mut libc::c_char = dc_mprintf(
b"%s \xe2\x80\x93 %s\x00" as *const u8 as *const libc::c_char,
subj,
(*part_1).msg,
part.msg,
);
free((*part_1).msg as *mut libc::c_void);
(*part_1).msg = new_txt;
free(part.msg as *mut libc::c_void);
part.msg = new_txt;
break;
} else {
i_0 += 1
}
}
}
@@ -309,30 +296,24 @@ pub unsafe fn dc_mimeparser_parse(
}
}
if 0 != (*mimeparser).is_forwarded {
let mut i_1: libc::c_int;
let icnt_0: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int;
i_1 = 0i32;
while i_1 < icnt_0 {
let part_2 =
carray_get((*mimeparser).parts, i_1 as libc::c_uint) as *mut dc_mimepart_t;
(*part_2).param.set_int(Param::Forwarded, 1);
i_1 += 1
for part in mimeparser.parts.iter_mut() {
part.param.set_int(Param::Forwarded, 1);
}
}
if carray_count((*mimeparser).parts) == 1i32 as libc::c_uint {
let mut part_3: *mut dc_mimepart_t =
carray_get((*mimeparser).parts, 0i32 as libc::c_uint) as *mut dc_mimepart_t;
if (*part_3).type_0 == 40i32 {
if mimeparser.parts.len() == 1 {
if mimeparser.parts[0].type_0 == 40i32 {
if !dc_mimeparser_lookup_optional_field(
mimeparser,
b"Chat-Voice-Message\x00" as *const u8 as *const libc::c_char,
)
.is_null()
{
(*part_3).type_0 = 41i32
let part_mut = &mut mimeparser.parts[0];
part_mut.type_0 = 41i32
}
}
if (*part_3).type_0 == 40i32 || (*part_3).type_0 == 41i32 || (*part_3).type_0 == 50i32 {
let part = &mimeparser.parts[0];
if part.type_0 == 40i32 || part.type_0 == 41i32 || part.type_0 == 50i32 {
let field_0 = dc_mimeparser_lookup_optional_field(
mimeparser,
b"Chat-Duration\x00" as *const u8 as *const libc::c_char,
@@ -340,7 +321,8 @@ pub unsafe fn dc_mimeparser_parse(
if !field_0.is_null() {
let duration_ms: libc::c_int = dc_atoi_null_is_0((*field_0).fld_value);
if duration_ms > 0i32 && duration_ms < 24i32 * 60i32 * 60i32 * 1000i32 {
(*part_3).param.set_int(Param::Duration, duration_ms);
let part_mut = &mut mimeparser.parts[0];
part_mut.param.set_int(Param::Duration, duration_ms);
}
}
}
@@ -350,7 +332,7 @@ pub unsafe fn dc_mimeparser_parse(
mimeparser,
b"Chat-Disposition-Notification-To\x00" as *const u8 as *const libc::c_char,
);
if !dn_field.is_null() && !dc_mimeparser_get_last_nonmeta(mimeparser).is_null() {
if !dn_field.is_null() && dc_mimeparser_get_last_nonmeta(mimeparser).is_some() {
let mut mb_list: *mut mailimf_mailbox_list = 0 as *mut mailimf_mailbox_list;
let mut index_0: size_t = 0i32 as size_t;
if mailimf_mailbox_list_parse(
@@ -374,10 +356,9 @@ pub unsafe fn dc_mimeparser_parse(
);
if !from_addr.is_null() {
if strcmp(from_addr, dn_to_addr) == 0i32 {
let part_4: *mut dc_mimepart_t =
dc_mimeparser_get_last_nonmeta(mimeparser);
if !part_4.is_null() {
(*part_4).param.set_int(Param::WantsMdn, 1);
if let Some(part_4) = dc_mimeparser_get_last_nonmeta(mimeparser)
{
part_4.param.set_int(Param::WantsMdn, 1);
}
}
free(from_addr as *mut libc::c_void);
@@ -391,7 +372,7 @@ pub unsafe fn dc_mimeparser_parse(
}
}
/* Cleanup - and try to create at least an empty part if there are no parts yet */
if dc_mimeparser_get_last_nonmeta(mimeparser).is_null() && (*mimeparser).reports.is_empty() {
if dc_mimeparser_get_last_nonmeta(mimeparser).is_none() && (*mimeparser).reports.is_empty() {
let mut part_5 = dc_mimepart_new();
part_5.type_0 = 10i32;
if !(*mimeparser).subject.is_null() && 0 == (*mimeparser).is_send_by_messenger {
@@ -399,11 +380,7 @@ pub unsafe fn dc_mimeparser_parse(
} else {
part_5.msg = dc_strdup(b"\x00" as *const u8 as *const libc::c_char)
}
carray_add(
(*mimeparser).parts,
Box::into_raw(Box::new(part_5)) as *mut libc::c_void,
0 as *mut libc::c_uint,
);
mimeparser.parts.push(part_5);
};
}
@@ -422,22 +399,14 @@ unsafe fn dc_mimepart_new() -> dc_mimepart_t {
}
}
pub unsafe fn dc_mimeparser_get_last_nonmeta(mimeparser: &dc_mimeparser_t) -> *mut dc_mimepart_t {
if !(*mimeparser).parts.is_null() {
let mut i: libc::c_int;
let icnt: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int;
i = icnt - 1i32;
while i >= 0i32 {
let part: *mut dc_mimepart_t =
carray_get(mimeparser.parts, i as libc::c_uint) as *mut dc_mimepart_t;
if !part.is_null() && 0 == (*part).is_meta {
return part;
}
i -= 1
}
}
0 as *mut dc_mimepart_t
pub fn dc_mimeparser_get_last_nonmeta<'a>(
mimeparser: &'a mut dc_mimeparser_t,
) -> Option<&'a mut dc_mimepart_t> {
mimeparser
.parts
.iter_mut()
.rev()
.find(|part| part.is_meta == 0)
}
/*the result must be freed*/
@@ -664,11 +633,7 @@ unsafe fn dc_mimeparser_parse_mime_recursive(
msg_body.as_ptr(),
);
part.msg_raw = dc_strdup(part.msg);
carray_add(
(*mimeparser).parts,
Box::into_raw(Box::new(part)) as *mut libc::c_void,
0 as *mut libc::c_uint,
);
mimeparser.parts.push(part);
any_part_added = 1i32;
(*mimeparser).decrypting_failed = 1i32
}
@@ -1125,7 +1090,7 @@ unsafe fn dc_mimeparser_add_single_part_if_known(
mime: *mut mailmime,
) -> libc::c_int {
let mut current_block: u64;
let old_part_count: libc::c_int = carray_count(mimeparser.parts) as libc::c_int;
let old_part_count = mimeparser.parts.len();
let mime_type: libc::c_int;
let mime_data: *mut mailmime_data;
let file_suffix: *mut libc::c_char = 0 as *mut libc::c_char;
@@ -1418,16 +1383,16 @@ unsafe fn dc_mimeparser_add_single_part_if_known(
free(file_suffix as *mut libc::c_void);
free(desired_filename as *mut libc::c_void);
free(raw_mime as *mut libc::c_void);
return if carray_count((*mimeparser).parts) > old_part_count as libc::c_uint {
1i32
return if mimeparser.parts.len() > old_part_count {
1
} else {
0i32
0
};
}
#[allow(non_snake_case)]
unsafe fn do_add_single_file_part(
parser: &dc_mimeparser_t,
parser: &mut dc_mimeparser_t,
msg_type: libc::c_int,
mime_type: libc::c_int,
raw_mime: *const libc::c_char,
@@ -1476,17 +1441,13 @@ unsafe fn do_add_single_file_part(
free(pathNfilename as *mut libc::c_void);
}
unsafe fn do_add_single_part(parser: &dc_mimeparser_t, mut part: dc_mimepart_t) {
unsafe fn do_add_single_part(parser: &mut dc_mimeparser_t, mut part: dc_mimepart_t) {
if 0 != (*parser).e2ee_helper.encrypted && (*parser).e2ee_helper.signatures.len() > 0 {
part.param.set_int(Param::GuranteeE2ee, 1);
} else if 0 != (*parser).e2ee_helper.encrypted {
part.param.set_int(Param::ErroneousE2ee, 0x2);
}
carray_add(
(*parser).parts,
Box::into_raw(Box::new(part)) as *mut libc::c_void,
0 as *mut libc::c_uint,
);
parser.parts.push(part);
}
// TODO should return bool /rtn
@@ -1773,27 +1734,20 @@ pub unsafe fn mailimf_find_field(
}
pub unsafe fn dc_mimeparser_repl_msg_by_error(
mimeparser: &dc_mimeparser_t,
mimeparser: &mut dc_mimeparser_t,
error_msg: *const libc::c_char,
) {
let mut part: *mut dc_mimepart_t;
let mut i: libc::c_int;
if (*mimeparser).parts.is_null() || carray_count((*mimeparser).parts) <= 0i32 as libc::c_uint {
if mimeparser.parts.is_empty() {
return;
}
part = carray_get((*mimeparser).parts, 0i32 as libc::c_uint) as *mut dc_mimepart_t;
(*part).type_0 = 10i32;
free((*part).msg as *mut libc::c_void);
(*part).msg = dc_mprintf(b"[%s]\x00" as *const u8 as *const libc::c_char, error_msg);
i = 1i32;
while (i as libc::c_uint) < carray_count((*mimeparser).parts) {
part = carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
if !part.is_null() {
dc_mimepart_unref(*Box::from_raw(part));
}
i += 1
let part = &mut mimeparser.parts[0];
part.type_0 = 10i32;
free(part.msg as *mut libc::c_void);
part.msg = dc_mprintf(b"[%s]\x00" as *const u8 as *const libc::c_char, error_msg);
for part in mimeparser.parts.drain(1..) {
dc_mimepart_unref(part);
}
carray_set_size((*mimeparser).parts, 1i32 as libc::c_uint);
assert_eq!(mimeparser.parts.len(), 1);
}
/*the result is a pointer to mime, must not be freed*/