diff --git a/src/context.rs b/src/context.rs index 4d52d658b..1bbc8a986 100644 --- a/src/context.rs +++ b/src/context.rs @@ -521,13 +521,13 @@ pub fn dc_get_fresh_msgs(context: &Context) -> *mut dc_array_t { &[10, 9, if 0 != show_deaddrop { 2 } else { 0 }], |row| row.get(0), |rows| { - let ret = unsafe { dc_array_new(128 as size_t) }; + let mut ret = dc_array_t::new(128); for row in rows { let id = row?; - unsafe { dc_array_add_id(ret, id) }; + ret.add_id(id); } - Ok(ret) + Ok(ret.as_ptr()) }, ) .unwrap() @@ -560,7 +560,7 @@ pub fn dc_search_msgs( AND ct.blocked=0 AND (m.txt LIKE ? OR ct.name LIKE ?) ORDER BY m.timestamp DESC,m.id DESC;" }; - let ret = unsafe { dc_array_new(100 as size_t) }; + let mut ret = dc_array_t::new(100); let success = context .sql @@ -570,7 +570,7 @@ pub fn dc_search_msgs( |row| row.get::<_, i32>(0), |rows| { for id in rows { - unsafe { dc_array_add_id(ret, id? as u32) }; + ret.add_id(id? as u32); } Ok(()) }, @@ -578,12 +578,9 @@ pub fn dc_search_msgs( .is_ok(); if success { - return ret; + return ret.as_ptr(); } - if !ret.is_null() { - unsafe { dc_array_unref(ret) }; - } std::ptr::null_mut() } diff --git a/src/dc_array.rs b/src/dc_array.rs index f62b2ee3f..15732a515 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -1,72 +1,160 @@ use crate::dc_location::dc_location; use crate::dc_tools::*; use crate::types::*; -use crate::x::*; - -const DC_ARRAY_MAGIC: uint32_t = 0x000a11aa; /* * the structure behind dc_array_t */ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct dc_array_t { - pub magic: uint32_t, - pub allocated: size_t, - pub count: size_t, - pub type_0: libc::c_int, - pub array: *mut uintptr_t, +#[derive(Clone)] +pub enum dc_array_t { + Locations(Vec), + Uint(Vec), } -/** - * @class dc_array_t - * - * An object containing a simple array. - * This object is used in several places where functions need to return an array. - * The items of the array are typically IDs. - * To free an array object, use dc_array_unref(). - */ -pub unsafe fn dc_array_unref(mut array: *mut dc_array_t) { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { - return; +impl dc_array_t { + pub fn new(capacity: usize) -> Self { + dc_array_t::Uint(Vec::with_capacity(capacity)) } - if (*array).type_0 == 1i32 { - dc_array_free_ptr(array); - } - free((*array).array as *mut libc::c_void); - (*array).magic = 0i32 as uint32_t; - free(array as *mut libc::c_void); -} -pub unsafe fn dc_array_free_ptr(array: *mut dc_array_t) { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { - return; + /// Constructs a new, empty `dc_array_t` holding locations with specified `capacity`. + pub fn new_locations(capacity: usize) -> Self { + dc_array_t::Locations(Vec::with_capacity(capacity)) } - let mut i: size_t = 0i32 as size_t; - while i < (*array).count { - Box::from_raw(*(*array).array.offset(i as isize) as *mut dc_location); - *(*array).array.offset(i as isize) = 0i32 as uintptr_t; - i = i.wrapping_add(1) + + pub fn as_ptr(self) -> *mut Self { + Box::into_raw(Box::new(self)) + } + + pub fn add_uint(&mut self, item: uintptr_t) { + if let Self::Uint(array) = self { + array.push(item); + } else { + panic!("Attempt to add uint to array of other type"); + } + } + + pub fn add_id(&mut self, item: uint32_t) { + self.add_uint(item as uintptr_t); + } + + pub fn add_location(&mut self, location: dc_location) { + if let Self::Locations(array) = self { + array.push(location) + } else { + panic!("Attempt to add a location to array of other type"); + } + } + + pub fn get_uint(&self, index: usize) -> uintptr_t { + if let Self::Uint(array) = self { + array[index] + } else { + panic!("Attempt to get uint from array of other type"); + } + } + + pub fn get_id(&self, index: usize) -> uint32_t { + match self { + Self::Locations(array) => array[index].location_id, + Self::Uint(array) => array[index] as uint32_t, + } + } + + pub fn get_ptr(&self, index: size_t) -> *mut libc::c_void { + if let Self::Uint(array) = self { + array[index] as *mut libc::c_void + } else { + panic!("Not an array of pointers"); + } + } + + pub fn get_location(&self, index: usize) -> &dc_location { + if let Self::Locations(array) = self { + &array[index] + } else { + panic!("Not an array of locations") + } + } + + pub fn get_latitude(&self, index: usize) -> libc::c_double { + self.get_location(index).latitude + } + + pub fn get_longitude(&self, index: size_t) -> libc::c_double { + self.get_location(index).longitude + } + + pub fn get_accuracy(&self, index: size_t) -> libc::c_double { + self.get_location(index).accuracy + } + + pub fn get_timestamp(&self, index: size_t) -> i64 { + self.get_location(index).timestamp + } + + pub fn get_chat_id(&self, index: size_t) -> uint32_t { + self.get_location(index).chat_id + } + + pub fn get_contact_id(&self, index: size_t) -> uint32_t { + self.get_location(index).contact_id + } + + pub fn get_msg_id(&self, index: size_t) -> uint32_t { + self.get_location(index).msg_id + } + + pub fn is_empty(&self) -> bool { + match self { + Self::Locations(array) => array.is_empty(), + Self::Uint(array) => array.is_empty(), + } + } + + /// Returns the number of elements in the array. + pub fn len(&self) -> usize { + match self { + Self::Locations(array) => array.len(), + Self::Uint(array) => array.len(), + } + } + + pub fn clear(&mut self) { + match self { + Self::Locations(array) => array.clear(), + Self::Uint(array) => array.clear(), + } + } + + pub fn search_id(&self, needle: uintptr_t) -> Option { + if let Self::Uint(array) = self { + for (i, &u) in array.iter().enumerate() { + if u == needle { + return Some(i); + } + } + None + } else { + panic!("Attempt to search for id in array of other type"); + } } } -pub unsafe fn dc_array_add_uint(mut array: *mut dc_array_t, item: uintptr_t) { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { +pub unsafe fn dc_array_unref(array: *mut dc_array_t) { + if array.is_null() { return; } - if (*array).count == (*array).allocated { - let newsize = (*array).allocated.wrapping_mul(2).wrapping_add(10); - (*array).array = realloc( - (*array).array as *mut libc::c_void, - (newsize).wrapping_mul(::std::mem::size_of::()), - ) as *mut uintptr_t; - assert!(!(*array).array.is_null()); - (*array).allocated = newsize as size_t + Box::from_raw(array); +} + +pub unsafe fn dc_array_add_uint(array: *mut dc_array_t, item: uintptr_t) { + if !array.is_null() { + (*array).add_uint(item); } - *(*array).array.offset((*array).count as isize) = item; - (*array).count = (*array).count.wrapping_add(1); } pub unsafe fn dc_array_add_id(array: *mut dc_array_t, item: uint32_t) { - dc_array_add_uint(array, item as uintptr_t); + if !array.is_null() { + (*array).add_id(item); + } } pub unsafe fn dc_array_add_ptr(array: *mut dc_array_t, item: *mut libc::c_void) { @@ -74,131 +162,104 @@ pub unsafe fn dc_array_add_ptr(array: *mut dc_array_t, item: *mut libc::c_void) } pub unsafe fn dc_array_get_cnt(array: *const dc_array_t) -> size_t { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { - return 0i32 as size_t; + if array.is_null() { + 0 + } else { + (*array).len() } - (*array).count } pub unsafe fn dc_array_get_uint(array: *const dc_array_t, index: size_t) -> uintptr_t { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count { - return 0i32 as uintptr_t; + if array.is_null() || index >= (*array).len() { + 0 + } else { + (*array).get_uint(index) } - *(*array).array.offset(index as isize) } pub unsafe fn dc_array_get_id(array: *const dc_array_t, index: size_t) -> uint32_t { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count { - return 0i32 as uint32_t; + if array.is_null() || index >= (*array).len() { + 0 + } else { + (*array).get_id(index) } - if (*array).type_0 == 1i32 { - return (*(*(*array).array.offset(index as isize) as *mut dc_location)).location_id; - } - *(*array).array.offset(index as isize) as uint32_t } pub unsafe fn dc_array_get_ptr(array: *const dc_array_t, index: size_t) -> *mut libc::c_void { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count { - return 0 as *mut libc::c_void; + if array.is_null() || index >= (*array).len() { + std::ptr::null_mut() + } else { + (*array).get_ptr(index) } - *(*array).array.offset(index as isize) as *mut libc::c_void } pub unsafe fn dc_array_get_latitude(array: *const dc_array_t, index: size_t) -> libc::c_double { - if array.is_null() - || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count - || (*array).type_0 != 1i32 - || *(*array).array.offset(index as isize) == 0 - { - return 0i32 as libc::c_double; + if array.is_null() || index >= (*array).len() { + 0.0 + } else { + (*array).get_latitude(index) } - (*(*(*array).array.offset(index as isize) as *mut dc_location)).latitude } pub unsafe fn dc_array_get_longitude(array: *const dc_array_t, index: size_t) -> libc::c_double { - if array.is_null() - || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count - || (*array).type_0 != 1i32 - || *(*array).array.offset(index as isize) == 0 - { - return 0i32 as libc::c_double; + if array.is_null() || index >= (*array).len() { + 0.0 + } else { + (*array).get_longitude(index) } - (*(*(*array).array.offset(index as isize) as *mut dc_location)).longitude } pub unsafe fn dc_array_get_accuracy(array: *const dc_array_t, index: size_t) -> libc::c_double { - if array.is_null() - || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count - || (*array).type_0 != 1i32 - || *(*array).array.offset(index as isize) == 0 - { - return 0i32 as libc::c_double; + if array.is_null() || index >= (*array).len() { + 0.0 + } else { + (*array).get_accuracy(index) } - (*(*(*array).array.offset(index as isize) as *mut dc_location)).accuracy } pub unsafe fn dc_array_get_timestamp(array: *const dc_array_t, index: size_t) -> i64 { - if array.is_null() - || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count - || (*array).type_0 != 1i32 - || *(*array).array.offset(index as isize) == 0 - { - return 0; + if array.is_null() || index >= (*array).len() { + 0 + } else { + (*array).get_timestamp(index) } - (*(*(*array).array.offset(index as isize) as *mut dc_location)).timestamp } pub unsafe fn dc_array_get_chat_id(array: *const dc_array_t, index: size_t) -> uint32_t { - if array.is_null() - || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count - || (*array).type_0 != 1i32 - || *(*array).array.offset(index as isize) == 0 - { - return 0i32 as uint32_t; + if array.is_null() || index >= (*array).len() { + 0 + } else { + (*array).get_chat_id(index) } - (*(*(*array).array.offset(index as isize) as *mut dc_location)).chat_id } pub unsafe fn dc_array_get_contact_id(array: *const dc_array_t, index: size_t) -> uint32_t { - if array.is_null() - || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count - || (*array).type_0 != 1i32 - || *(*array).array.offset(index as isize) == 0 - { - return 0i32 as uint32_t; + if array.is_null() || index >= (*array).len() { + 0 + } else { + (*array).get_contact_id(index) } - (*(*(*array).array.offset(index as isize) as *mut dc_location)).contact_id } pub unsafe fn dc_array_get_msg_id(array: *const dc_array_t, index: size_t) -> uint32_t { - if array.is_null() - || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count - || (*array).type_0 != 1i32 - || *(*array).array.offset(index as isize) == 0 - { - return 0i32 as uint32_t; + if array.is_null() || index >= (*array).len() { + 0 + } else { + (*array).get_msg_id(index) } - (*(*(*array).array.offset(index as isize) as *mut dc_location)).msg_id } pub unsafe fn dc_array_get_marker(array: *const dc_array_t, index: size_t) -> *mut libc::c_char { - if array.is_null() - || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count - || (*array).type_0 != 1i32 - || *(*array).array.offset(index as isize) == 0 - { - return 0 as *mut libc::c_char; + if array.is_null() || index >= (*array).len() { + return std::ptr::null_mut(); } - if let Some(s) = &(*(*(*array).array.offset(index as isize) as *mut dc_location)).marker { - to_cstring(s) + + if let dc_array_t::Locations(v) = &*array { + if let Some(s) = &v[index].marker { + to_cstring(s) + } else { + std::ptr::null_mut() + } } else { std::ptr::null_mut() } @@ -215,16 +276,15 @@ pub unsafe fn dc_array_get_marker(array: *const dc_array_t, index: size_t) -> *m * 1=Location was reported independently. */ pub unsafe fn dc_array_is_independent(array: *const dc_array_t, index: size_t) -> libc::c_int { - if array.is_null() - || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count - || (*array).type_0 != 1i32 - || *(*array).array.offset(index as isize) == 0 - { + if array.is_null() || index >= (*array).len() { return 0; } - (*(*(*array).array.offset(index as isize) as *mut dc_location)).independent as libc::c_int + if let dc_array_t::Locations(v) = &*array { + v[index].independent as libc::c_int + } else { + panic!("Attempt to get location independent field from array of something other than locations"); + } } pub unsafe fn dc_array_search_id( @@ -232,154 +292,95 @@ pub unsafe fn dc_array_search_id( needle: uint32_t, ret_index: *mut size_t, ) -> bool { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { + if array.is_null() { return false; } - let data: *mut uintptr_t = (*array).array; - let mut i: size_t = 0; - let cnt: size_t = (*array).count; - while i < cnt { - if *data.offset(i as isize) == needle as size_t { - if !ret_index.is_null() { - *ret_index = i - } - return true; + if let Some(i) = (*array).search_id(needle as uintptr_t) { + if !ret_index.is_null() { + *ret_index = i } - i = i.wrapping_add(1) + true + } else { + false } - false } pub unsafe fn dc_array_get_raw(array: *const dc_array_t) -> *const uintptr_t { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { + if array.is_null() { return 0 as *const uintptr_t; } - (*array).array -} - -pub unsafe fn dc_array_new(initsize: size_t) -> *mut dc_array_t { - dc_array_new_typed(0, initsize) -} - -pub unsafe fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut dc_array_t { - let mut array: *mut dc_array_t; - array = calloc(1, ::std::mem::size_of::()) as *mut dc_array_t; - assert!(!array.is_null()); - - (*array).magic = DC_ARRAY_MAGIC; - (*array).count = 0i32 as size_t; - (*array).allocated = if initsize < 1 { 1 } else { initsize }; - (*array).type_0 = type_0; - (*array).array = malloc( - (*array) - .allocated - .wrapping_mul(::std::mem::size_of::()), - ) as *mut uintptr_t; - if (*array).array.is_null() { - exit(48i32); + if let dc_array_t::Uint(v) = &*array { + v.as_ptr() + } else { + panic!("Attempt to convert array of something other than uints to raw"); } - array } -pub unsafe fn dc_array_empty(mut array: *mut dc_array_t) { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { +pub fn dc_array_new(initsize: size_t) -> *mut dc_array_t { + dc_array_t::new(initsize).as_ptr() +} + +pub fn dc_array_new_locations(initsize: size_t) -> *mut dc_array_t { + dc_array_t::new_locations(initsize).as_ptr() +} + +pub unsafe fn dc_array_empty(array: *mut dc_array_t) { + if array.is_null() { return; } - (*array).count = 0i32 as size_t; + (*array).clear() } pub unsafe fn dc_array_duplicate(array: *const dc_array_t) -> *mut dc_array_t { - let mut ret: *mut dc_array_t; - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { - return 0 as *mut dc_array_t; + if array.is_null() { + std::ptr::null_mut() + } else { + (*array).clone().as_ptr() } - ret = dc_array_new((*array).allocated); - (*ret).count = (*array).count; - memcpy( - (*ret).array as *mut libc::c_void, - (*array).array as *const libc::c_void, - (*array) - .count - .wrapping_mul(::std::mem::size_of::()), - ); - ret } pub unsafe fn dc_array_sort_ids(array: *mut dc_array_t) { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || (*array).count <= 1 { + if array.is_null() || (*array).len() <= 1 { return; } - qsort( - (*array).array as *mut libc::c_void, - (*array).count, - ::std::mem::size_of::(), - Some(cmp_intptr_t), - ); -} - -unsafe extern "C" fn cmp_intptr_t(p1: *const libc::c_void, p2: *const libc::c_void) -> libc::c_int { - let v1: uintptr_t = *(p1 as *mut uintptr_t); - let v2: uintptr_t = *(p2 as *mut uintptr_t); - return if v1 < v2 { - -1i32 - } else if v1 > v2 { - 1i32 + if let dc_array_t::Uint(v) = &mut *array { + v.sort(); } else { - 0i32 - }; -} - -pub unsafe fn dc_array_sort_strings(array: *mut dc_array_t) { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || (*array).count <= 1 { - return; + panic!("Attempt to sort array of something other than uints"); } - qsort( - (*array).array as *mut libc::c_void, - (*array).count, - ::std::mem::size_of::<*mut libc::c_char>(), - Some(cmp_strings_t), - ); -} - -unsafe extern "C" fn cmp_strings_t( - p1: *const libc::c_void, - p2: *const libc::c_void, -) -> libc::c_int { - let v1: *const libc::c_char = *(p1 as *mut *const libc::c_char); - let v2: *const libc::c_char = *(p2 as *mut *const libc::c_char); - - strcmp(v1, v2) } pub unsafe fn dc_array_get_string( array: *const dc_array_t, sep: *const libc::c_char, ) -> *mut libc::c_char { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || sep.is_null() { + if array.is_null() || sep.is_null() { return dc_strdup(b"\x00" as *const u8 as *const libc::c_char); } - let cnt = (*array).count as usize; - let slice = std::slice::from_raw_parts((*array).array, cnt); - let sep = as_str(sep); + if let dc_array_t::Uint(v) = &*array { + let cnt = v.len(); + let sep = as_str(sep); - let res = slice - .iter() - .enumerate() - .fold(String::with_capacity(2 * cnt), |mut res, (i, n)| { - if i == 0 { - res += &n.to_string(); - } else { - res += sep; - res += &n.to_string(); - } - res - }); - to_cstring(res) + let res = v + .iter() + .enumerate() + .fold(String::with_capacity(2 * cnt), |res, (i, n)| { + if i == 0 { + res + &n.to_string() + } else { + res + sep + &n.to_string() + } + }); + to_cstring(res) + } else { + panic!("Attempt to get string from array of other type"); + } } #[cfg(test)] mod tests { use super::*; + use crate::x::*; use std::ffi::CStr; #[test] @@ -429,38 +430,6 @@ mod tests { ); free(str as *mut libc::c_void); - dc_array_empty(arr); - - dc_array_add_ptr( - arr, - b"XX\x00" as *const u8 as *const libc::c_char as *mut libc::c_void, - ); - dc_array_add_ptr( - arr, - b"item1\x00" as *const u8 as *const libc::c_char as *mut libc::c_void, - ); - dc_array_add_ptr( - arr, - b"bbb\x00" as *const u8 as *const libc::c_char as *mut libc::c_void, - ); - dc_array_add_ptr( - arr, - b"aaa\x00" as *const u8 as *const libc::c_char as *mut libc::c_void, - ); - dc_array_sort_strings(arr); - - let str = dc_array_get_ptr(arr, 0 as size_t) as *mut libc::c_char; - assert_eq!(CStr::from_ptr(str).to_str().unwrap(), "XX"); - - let str = dc_array_get_ptr(arr, 1 as size_t) as *mut libc::c_char; - assert_eq!(CStr::from_ptr(str).to_str().unwrap(), "aaa"); - - let str = dc_array_get_ptr(arr, 2 as size_t) as *mut libc::c_char; - assert_eq!(CStr::from_ptr(str).to_str().unwrap(), "bbb"); - - let str = dc_array_get_ptr(arr, 3 as size_t) as *mut libc::c_char; - assert_eq!(CStr::from_ptr(str).to_str().unwrap(), "item1"); - dc_array_unref(arr); } } diff --git a/src/dc_chat.rs b/src/dc_chat.rs index ca6a77021..74895c6e7 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -1094,14 +1094,13 @@ pub unsafe fn dc_get_draft(context: &Context, chat_id: uint32_t) -> *mut dc_msg_ draft_msg } -pub unsafe fn dc_get_chat_msgs( +pub fn dc_get_chat_msgs( context: &Context, chat_id: uint32_t, flags: uint32_t, marker1before: uint32_t, ) -> *mut dc_array_t { - let ret = dc_array_new(512); - assert!(!ret.is_null()); + let mut ret = dc_array_t::new(512); let mut last_day = 0; let cnv_to_local = dc_gm2local_offset(); @@ -1111,17 +1110,17 @@ pub unsafe fn dc_get_chat_msgs( for row in rows { let (curr_id, ts) = row?; if curr_id as u32 == marker1before { - dc_array_add_id(ret, 1); + ret.add_id(1); } if 0 != flags & 0x1 { let curr_local_timestamp = ts + cnv_to_local; let curr_day = (curr_local_timestamp / 86400) as libc::c_int; if curr_day != last_day { - dc_array_add_id(ret, 9); + ret.add_id(9); last_day = curr_day; } } - dc_array_add_id(ret, curr_id as u32); + ret.add_id(curr_id as u32); } Ok(()) }; @@ -1169,11 +1168,8 @@ pub unsafe fn dc_get_chat_msgs( }; if success.is_ok() { - ret + ret.as_ptr() } else { - if !ret.is_null() { - dc_array_unref(ret); - } 0 as *mut dc_array_t } } @@ -1285,11 +1281,11 @@ pub fn dc_get_chat_media( ], |row| row.get::<_, i32>(0), |ids| { - let ret = unsafe { dc_array_new(100) }; + let mut ret = dc_array_t::new(100); for id in ids { - unsafe { dc_array_add_id(ret, id? as u32) }; + ret.add_id(id? as u32); } - Ok(ret) + Ok(ret.as_ptr()) } ).unwrap_or_else(|_| std::ptr::null_mut()) } @@ -1458,13 +1454,13 @@ pub fn dc_get_chat_contacts(context: &Context, chat_id: u32) -> *mut dc_array_t params![chat_id as i32], |row| row.get::<_, i32>(0), |ids| { - let ret = unsafe { dc_array_new(100) }; + let mut ret = dc_array_t::new(100); for id in ids { - unsafe { dc_array_add_id(ret, id? as u32) }; + ret.add_id(id? as u32); } - Ok(ret) + Ok(ret.as_ptr()) }, ) .unwrap_or_else(|_| std::ptr::null_mut()) @@ -2168,11 +2164,8 @@ pub unsafe fn dc_chat_get_profile_image(chat: *const Chat) -> *mut libc::c_char image_abs = dc_get_abs_path((*chat).context, image_rel) } else if (*chat).type_0 == 100i32 { contacts = dc_get_chat_contacts((*chat).context, (*chat).id); - if (*contacts).count >= 1 { - contact = dc_get_contact( - (*chat).context, - *(*contacts).array.offset(0isize) as uint32_t, - ); + if !(*contacts).is_empty() { + contact = dc_get_contact((*chat).context, (*contacts).get_id(0)); image_abs = dc_contact_get_profile_image(contact) } } @@ -2192,11 +2185,8 @@ pub unsafe fn dc_chat_get_color(chat: *const Chat) -> uint32_t { if !(chat.is_null() || (*chat).magic != 0xc4a7c4a7u32) { if (*chat).type_0 == 100i32 { contacts = dc_get_chat_contacts((*chat).context, (*chat).id); - if (*contacts).count >= 1 { - contact = dc_get_contact( - (*chat).context, - *(*contacts).array.offset(0isize) as uint32_t, - ); + if !(*contacts).is_empty() { + contact = dc_get_contact((*chat).context, (*contacts).get_id(0)); color = dc_str_to_color((*contact).addr) as uint32_t } } else { diff --git a/src/dc_contact.rs b/src/dc_contact.rs index 4a3a62afd..a10a6bfba 100644 --- a/src/dc_contact.rs +++ b/src/dc_contact.rs @@ -537,7 +537,7 @@ pub fn dc_get_contacts( .unwrap_or_default(); let mut add_self = false; - let ret = unsafe { dc_array_new(100) }; + let mut ret = dc_array_t::new(100); if (listflags & DC_GCL_VERIFIED_ONLY) > 0 || !query.is_null() { let s3strLikeCmd = format!("%{}%", if !query.is_null() { as_str(query) } else { "" }); @@ -565,7 +565,7 @@ pub fn dc_get_contacts( |row| row.get::<_, i32>(0), |ids| { for id in ids { - unsafe { dc_array_add_id(ret, id? as u32) }; + ret.add_id(id? as u32); } Ok(()) }, @@ -595,7 +595,7 @@ pub fn dc_get_contacts( |row| row.get::<_, i32>(0), |ids| { for id in ids { - unsafe { dc_array_add_id(ret, id? as u32) }; + ret.add_id(id? as u32); } Ok(()) } @@ -603,10 +603,10 @@ pub fn dc_get_contacts( } if 0 != listflags & 0x2 && add_self { - unsafe { dc_array_add_id(ret, 1) }; + ret.add_id(1); } - ret + ret.as_ptr() } pub fn dc_get_blocked_cnt(context: &Context) -> libc::c_int { @@ -629,13 +629,13 @@ pub fn dc_get_blocked_contacts(context: &Context) -> *mut dc_array_t { params![9], |row| row.get::<_, i32>(0), |ids| { - let ret = unsafe { dc_array_new(100) }; + let mut ret = dc_array_t::new(100); for id in ids { - unsafe { dc_array_add_id(ret, id? as u32) }; + ret.add_id(id? as u32); } - Ok(ret) + Ok(ret.as_ptr()) }, ) .unwrap_or_else(|_| std::ptr::null_mut()) diff --git a/src/dc_location.rs b/src/dc_location.rs index 2a89d84ab..7401fda9f 100644 --- a/src/dc_location.rs +++ b/src/dc_location.rs @@ -247,17 +247,12 @@ pub fn dc_get_locations( Ok(loc) }, |locations| { - let ret = unsafe { dc_array_new_typed(1, 500) }; + let mut ret = dc_array_t::new_locations(500); for location in locations { - unsafe { - dc_array_add_ptr( - ret, - Box::into_raw(Box::new(location?)) as *mut libc::c_void, - ) - }; + ret.add_location(location?); } - Ok(ret) + Ok(ret.as_ptr()) }, ) .unwrap_or_else(|_| std::ptr::null_mut()) @@ -501,7 +496,7 @@ pub unsafe fn dc_kml_parse( } else { content_nullterminated = dc_null_terminate(content, content_bytes as libc::c_int); if !content_nullterminated.is_null() { - kml.locations = dc_array_new_typed(1, 100 as size_t); + kml.locations = dc_array_new_locations(100); dc_saxparser_init( &mut saxparser, &mut kml as *mut dc_kml_t as *mut libc::c_void, @@ -587,10 +582,7 @@ unsafe fn kml_endtag_cb(userdata: *mut libc::c_void, tag: *const libc::c_char) { && 0. != (*kml).curr.longitude { let location = (*kml).curr.clone(); - dc_array_add_ptr( - (*kml).locations, - Box::into_raw(Box::new(location)) as *mut libc::c_void, - ); + (*(*kml).locations).add_location(location); } (*kml).tag = 0 };