Merge pull request #211 from link2xt/dc_array-cleanup

dc_array_t cleanup
This commit is contained in:
Friedel Ziegelmayer
2019-07-28 11:51:08 +02:00
committed by GitHub
5 changed files with 282 additions and 334 deletions

View File

@@ -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 }], &[10, 9, if 0 != show_deaddrop { 2 } else { 0 }],
|row| row.get(0), |row| row.get(0),
|rows| { |rows| {
let ret = unsafe { dc_array_new(128 as size_t) }; let mut ret = dc_array_t::new(128);
for row in rows { for row in rows {
let id = row?; let id = row?;
unsafe { dc_array_add_id(ret, id) }; ret.add_id(id);
} }
Ok(ret) Ok(ret.as_ptr())
}, },
) )
.unwrap() .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;" 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 let success = context
.sql .sql
@@ -570,7 +570,7 @@ pub fn dc_search_msgs(
|row| row.get::<_, i32>(0), |row| row.get::<_, i32>(0),
|rows| { |rows| {
for id in rows { for id in rows {
unsafe { dc_array_add_id(ret, id? as u32) }; ret.add_id(id? as u32);
} }
Ok(()) Ok(())
}, },
@@ -578,12 +578,9 @@ pub fn dc_search_msgs(
.is_ok(); .is_ok();
if success { if success {
return ret; return ret.as_ptr();
} }
if !ret.is_null() {
unsafe { dc_array_unref(ret) };
}
std::ptr::null_mut() std::ptr::null_mut()
} }

View File

@@ -1,72 +1,160 @@
use crate::dc_location::dc_location; use crate::dc_location::dc_location;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::types::*; use crate::types::*;
use crate::x::*;
const DC_ARRAY_MAGIC: uint32_t = 0x000a11aa;
/* * the structure behind dc_array_t */ /* * the structure behind dc_array_t */
#[derive(Copy, Clone)] #[derive(Clone)]
#[repr(C)] pub enum dc_array_t {
pub struct dc_array_t { Locations(Vec<dc_location>),
pub magic: uint32_t, Uint(Vec<uintptr_t>),
pub allocated: size_t,
pub count: size_t,
pub type_0: libc::c_int,
pub array: *mut uintptr_t,
} }
/** impl dc_array_t {
* @class dc_array_t pub fn new(capacity: usize) -> Self {
* dc_array_t::Uint(Vec::with_capacity(capacity))
* 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;
} }
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) { /// Constructs a new, empty `dc_array_t` holding locations with specified `capacity`.
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { pub fn new_locations(capacity: usize) -> Self {
return; dc_array_t::Locations(Vec::with_capacity(capacity))
} }
let mut i: size_t = 0i32 as size_t;
while i < (*array).count { pub fn as_ptr(self) -> *mut Self {
Box::from_raw(*(*array).array.offset(i as isize) as *mut dc_location); Box::into_raw(Box::new(self))
*(*array).array.offset(i as isize) = 0i32 as uintptr_t; }
i = i.wrapping_add(1)
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<usize> {
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) { pub unsafe fn dc_array_unref(array: *mut dc_array_t) {
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { if array.is_null() {
return; return;
} }
if (*array).count == (*array).allocated { Box::from_raw(array);
let newsize = (*array).allocated.wrapping_mul(2).wrapping_add(10); }
(*array).array = realloc(
(*array).array as *mut libc::c_void, pub unsafe fn dc_array_add_uint(array: *mut dc_array_t, item: uintptr_t) {
(newsize).wrapping_mul(::std::mem::size_of::<uintptr_t>()), if !array.is_null() {
) as *mut uintptr_t; (*array).add_uint(item);
assert!(!(*array).array.is_null());
(*array).allocated = newsize as size_t
} }
*(*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) { 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) { 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 { pub unsafe fn dc_array_get_cnt(array: *const dc_array_t) -> size_t {
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { if array.is_null() {
return 0i32 as size_t; 0
} else {
(*array).len()
} }
(*array).count
} }
pub unsafe fn dc_array_get_uint(array: *const dc_array_t, index: size_t) -> uintptr_t { 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 { if array.is_null() || index >= (*array).len() {
return 0i32 as uintptr_t; 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 { 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 { if array.is_null() || index >= (*array).len() {
return 0i32 as uint32_t; 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 { 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 { if array.is_null() || index >= (*array).len() {
return 0 as *mut libc::c_void; 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 { pub unsafe fn dc_array_get_latitude(array: *const dc_array_t, index: size_t) -> libc::c_double {
if array.is_null() if array.is_null() || index >= (*array).len() {
|| (*array).magic != DC_ARRAY_MAGIC 0.0
|| index >= (*array).count } else {
|| (*array).type_0 != 1i32 (*array).get_latitude(index)
|| *(*array).array.offset(index as isize) == 0
{
return 0i32 as libc::c_double;
} }
(*(*(*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 { pub unsafe fn dc_array_get_longitude(array: *const dc_array_t, index: size_t) -> libc::c_double {
if array.is_null() if array.is_null() || index >= (*array).len() {
|| (*array).magic != DC_ARRAY_MAGIC 0.0
|| index >= (*array).count } else {
|| (*array).type_0 != 1i32 (*array).get_longitude(index)
|| *(*array).array.offset(index as isize) == 0
{
return 0i32 as libc::c_double;
} }
(*(*(*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 { pub unsafe fn dc_array_get_accuracy(array: *const dc_array_t, index: size_t) -> libc::c_double {
if array.is_null() if array.is_null() || index >= (*array).len() {
|| (*array).magic != DC_ARRAY_MAGIC 0.0
|| index >= (*array).count } else {
|| (*array).type_0 != 1i32 (*array).get_accuracy(index)
|| *(*array).array.offset(index as isize) == 0
{
return 0i32 as libc::c_double;
} }
(*(*(*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 { pub unsafe fn dc_array_get_timestamp(array: *const dc_array_t, index: size_t) -> i64 {
if array.is_null() if array.is_null() || index >= (*array).len() {
|| (*array).magic != DC_ARRAY_MAGIC 0
|| index >= (*array).count } else {
|| (*array).type_0 != 1i32 (*array).get_timestamp(index)
|| *(*array).array.offset(index as isize) == 0
{
return 0;
} }
(*(*(*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 { pub unsafe fn dc_array_get_chat_id(array: *const dc_array_t, index: size_t) -> uint32_t {
if array.is_null() if array.is_null() || index >= (*array).len() {
|| (*array).magic != DC_ARRAY_MAGIC 0
|| index >= (*array).count } else {
|| (*array).type_0 != 1i32 (*array).get_chat_id(index)
|| *(*array).array.offset(index as isize) == 0
{
return 0i32 as uint32_t;
} }
(*(*(*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 { pub unsafe fn dc_array_get_contact_id(array: *const dc_array_t, index: size_t) -> uint32_t {
if array.is_null() if array.is_null() || index >= (*array).len() {
|| (*array).magic != DC_ARRAY_MAGIC 0
|| index >= (*array).count } else {
|| (*array).type_0 != 1i32 (*array).get_contact_id(index)
|| *(*array).array.offset(index as isize) == 0
{
return 0i32 as uint32_t;
} }
(*(*(*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 { pub unsafe fn dc_array_get_msg_id(array: *const dc_array_t, index: size_t) -> uint32_t {
if array.is_null() if array.is_null() || index >= (*array).len() {
|| (*array).magic != DC_ARRAY_MAGIC 0
|| index >= (*array).count } else {
|| (*array).type_0 != 1i32 (*array).get_msg_id(index)
|| *(*array).array.offset(index as isize) == 0
{
return 0i32 as uint32_t;
} }
(*(*(*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 { pub unsafe fn dc_array_get_marker(array: *const dc_array_t, index: size_t) -> *mut libc::c_char {
if array.is_null() if array.is_null() || index >= (*array).len() {
|| (*array).magic != DC_ARRAY_MAGIC return std::ptr::null_mut();
|| index >= (*array).count
|| (*array).type_0 != 1i32
|| *(*array).array.offset(index as isize) == 0
{
return 0 as *mut libc::c_char;
} }
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 { } else {
std::ptr::null_mut() 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. * 1=Location was reported independently.
*/ */
pub unsafe fn dc_array_is_independent(array: *const dc_array_t, index: size_t) -> libc::c_int { pub unsafe fn dc_array_is_independent(array: *const dc_array_t, index: size_t) -> libc::c_int {
if array.is_null() if array.is_null() || index >= (*array).len() {
|| (*array).magic != DC_ARRAY_MAGIC
|| index >= (*array).count
|| (*array).type_0 != 1i32
|| *(*array).array.offset(index as isize) == 0
{
return 0; 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( pub unsafe fn dc_array_search_id(
@@ -232,154 +292,95 @@ pub unsafe fn dc_array_search_id(
needle: uint32_t, needle: uint32_t,
ret_index: *mut size_t, ret_index: *mut size_t,
) -> bool { ) -> bool {
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { if array.is_null() {
return false; return false;
} }
let data: *mut uintptr_t = (*array).array; if let Some(i) = (*array).search_id(needle as uintptr_t) {
let mut i: size_t = 0; if !ret_index.is_null() {
let cnt: size_t = (*array).count; *ret_index = i
while i < cnt {
if *data.offset(i as isize) == needle as size_t {
if !ret_index.is_null() {
*ret_index = i
}
return true;
} }
i = i.wrapping_add(1) true
} else {
false
} }
false
} }
pub unsafe fn dc_array_get_raw(array: *const dc_array_t) -> *const uintptr_t { 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; return 0 as *const uintptr_t;
} }
(*array).array if let dc_array_t::Uint(v) = &*array {
} v.as_ptr()
} else {
pub unsafe fn dc_array_new(initsize: size_t) -> *mut dc_array_t { panic!("Attempt to convert array of something other than uints to raw");
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::<dc_array_t>()) 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::<uintptr_t>()),
) as *mut uintptr_t;
if (*array).array.is_null() {
exit(48i32);
} }
array
} }
pub unsafe fn dc_array_empty(mut array: *mut dc_array_t) { pub fn dc_array_new(initsize: size_t) -> *mut dc_array_t {
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { 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; return;
} }
(*array).count = 0i32 as size_t; (*array).clear()
} }
pub unsafe fn dc_array_duplicate(array: *const dc_array_t) -> *mut dc_array_t { 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() {
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { std::ptr::null_mut()
return 0 as *mut dc_array_t; } 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::<uintptr_t>()),
);
ret
} }
pub unsafe fn dc_array_sort_ids(array: *mut dc_array_t) { 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; return;
} }
qsort( if let dc_array_t::Uint(v) = &mut *array {
(*array).array as *mut libc::c_void, v.sort();
(*array).count,
::std::mem::size_of::<uintptr_t>(),
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
} else { } else {
0i32 panic!("Attempt to sort array of something other than uints");
};
}
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;
} }
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( pub unsafe fn dc_array_get_string(
array: *const dc_array_t, array: *const dc_array_t,
sep: *const libc::c_char, sep: *const libc::c_char,
) -> *mut 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); return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
} }
let cnt = (*array).count as usize; if let dc_array_t::Uint(v) = &*array {
let slice = std::slice::from_raw_parts((*array).array, cnt); let cnt = v.len();
let sep = as_str(sep); let sep = as_str(sep);
let res = slice let res = v
.iter() .iter()
.enumerate() .enumerate()
.fold(String::with_capacity(2 * cnt), |mut res, (i, n)| { .fold(String::with_capacity(2 * cnt), |res, (i, n)| {
if i == 0 { if i == 0 {
res += &n.to_string(); res + &n.to_string()
} else { } else {
res += sep; res + sep + &n.to_string()
res += &n.to_string(); }
} });
res to_cstring(res)
}); } else {
to_cstring(res) panic!("Attempt to get string from array of other type");
}
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::x::*;
use std::ffi::CStr; use std::ffi::CStr;
#[test] #[test]
@@ -429,38 +430,6 @@ mod tests {
); );
free(str as *mut libc::c_void); 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); dc_array_unref(arr);
} }
} }

View File

@@ -1094,14 +1094,13 @@ pub unsafe fn dc_get_draft(context: &Context, chat_id: uint32_t) -> *mut dc_msg_
draft_msg draft_msg
} }
pub unsafe fn dc_get_chat_msgs( pub fn dc_get_chat_msgs(
context: &Context, context: &Context,
chat_id: uint32_t, chat_id: uint32_t,
flags: uint32_t, flags: uint32_t,
marker1before: uint32_t, marker1before: uint32_t,
) -> *mut dc_array_t { ) -> *mut dc_array_t {
let ret = dc_array_new(512); let mut ret = dc_array_t::new(512);
assert!(!ret.is_null());
let mut last_day = 0; let mut last_day = 0;
let cnv_to_local = dc_gm2local_offset(); let cnv_to_local = dc_gm2local_offset();
@@ -1111,17 +1110,17 @@ pub unsafe fn dc_get_chat_msgs(
for row in rows { for row in rows {
let (curr_id, ts) = row?; let (curr_id, ts) = row?;
if curr_id as u32 == marker1before { if curr_id as u32 == marker1before {
dc_array_add_id(ret, 1); ret.add_id(1);
} }
if 0 != flags & 0x1 { if 0 != flags & 0x1 {
let curr_local_timestamp = ts + cnv_to_local; let curr_local_timestamp = ts + cnv_to_local;
let curr_day = (curr_local_timestamp / 86400) as libc::c_int; let curr_day = (curr_local_timestamp / 86400) as libc::c_int;
if curr_day != last_day { if curr_day != last_day {
dc_array_add_id(ret, 9); ret.add_id(9);
last_day = curr_day; last_day = curr_day;
} }
} }
dc_array_add_id(ret, curr_id as u32); ret.add_id(curr_id as u32);
} }
Ok(()) Ok(())
}; };
@@ -1169,11 +1168,8 @@ pub unsafe fn dc_get_chat_msgs(
}; };
if success.is_ok() { if success.is_ok() {
ret ret.as_ptr()
} else { } else {
if !ret.is_null() {
dc_array_unref(ret);
}
0 as *mut dc_array_t 0 as *mut dc_array_t
} }
} }
@@ -1285,11 +1281,11 @@ pub fn dc_get_chat_media(
], ],
|row| row.get::<_, i32>(0), |row| row.get::<_, i32>(0),
|ids| { |ids| {
let ret = unsafe { dc_array_new(100) }; let mut ret = dc_array_t::new(100);
for id in ids { 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()) ).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], params![chat_id as i32],
|row| row.get::<_, i32>(0), |row| row.get::<_, i32>(0),
|ids| { |ids| {
let ret = unsafe { dc_array_new(100) }; let mut ret = dc_array_t::new(100);
for id in ids { 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()) .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) image_abs = dc_get_abs_path((*chat).context, image_rel)
} else if (*chat).type_0 == 100i32 { } else if (*chat).type_0 == 100i32 {
contacts = dc_get_chat_contacts((*chat).context, (*chat).id); contacts = dc_get_chat_contacts((*chat).context, (*chat).id);
if (*contacts).count >= 1 { if !(*contacts).is_empty() {
contact = dc_get_contact( contact = dc_get_contact((*chat).context, (*contacts).get_id(0));
(*chat).context,
*(*contacts).array.offset(0isize) as uint32_t,
);
image_abs = dc_contact_get_profile_image(contact) 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.is_null() || (*chat).magic != 0xc4a7c4a7u32) {
if (*chat).type_0 == 100i32 { if (*chat).type_0 == 100i32 {
contacts = dc_get_chat_contacts((*chat).context, (*chat).id); contacts = dc_get_chat_contacts((*chat).context, (*chat).id);
if (*contacts).count >= 1 { if !(*contacts).is_empty() {
contact = dc_get_contact( contact = dc_get_contact((*chat).context, (*contacts).get_id(0));
(*chat).context,
*(*contacts).array.offset(0isize) as uint32_t,
);
color = dc_str_to_color((*contact).addr) as uint32_t color = dc_str_to_color((*contact).addr) as uint32_t
} }
} else { } else {

View File

@@ -537,7 +537,7 @@ pub fn dc_get_contacts(
.unwrap_or_default(); .unwrap_or_default();
let mut add_self = false; 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() { if (listflags & DC_GCL_VERIFIED_ONLY) > 0 || !query.is_null() {
let s3strLikeCmd = format!("%{}%", if !query.is_null() { as_str(query) } else { "" }); 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), |row| row.get::<_, i32>(0),
|ids| { |ids| {
for id in ids { for id in ids {
unsafe { dc_array_add_id(ret, id? as u32) }; ret.add_id(id? as u32);
} }
Ok(()) Ok(())
}, },
@@ -595,7 +595,7 @@ pub fn dc_get_contacts(
|row| row.get::<_, i32>(0), |row| row.get::<_, i32>(0),
|ids| { |ids| {
for id in ids { for id in ids {
unsafe { dc_array_add_id(ret, id? as u32) }; ret.add_id(id? as u32);
} }
Ok(()) Ok(())
} }
@@ -603,10 +603,10 @@ pub fn dc_get_contacts(
} }
if 0 != listflags & 0x2 && add_self { 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 { 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], params![9],
|row| row.get::<_, i32>(0), |row| row.get::<_, i32>(0),
|ids| { |ids| {
let ret = unsafe { dc_array_new(100) }; let mut ret = dc_array_t::new(100);
for id in ids { 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()) .unwrap_or_else(|_| std::ptr::null_mut())

View File

@@ -247,17 +247,12 @@ pub fn dc_get_locations(
Ok(loc) Ok(loc)
}, },
|locations| { |locations| {
let ret = unsafe { dc_array_new_typed(1, 500) }; let mut ret = dc_array_t::new_locations(500);
for location in locations { for location in locations {
unsafe { ret.add_location(location?);
dc_array_add_ptr(
ret,
Box::into_raw(Box::new(location?)) as *mut libc::c_void,
)
};
} }
Ok(ret) Ok(ret.as_ptr())
}, },
) )
.unwrap_or_else(|_| std::ptr::null_mut()) .unwrap_or_else(|_| std::ptr::null_mut())
@@ -501,7 +496,7 @@ pub unsafe fn dc_kml_parse(
} else { } else {
content_nullterminated = dc_null_terminate(content, content_bytes as libc::c_int); content_nullterminated = dc_null_terminate(content, content_bytes as libc::c_int);
if !content_nullterminated.is_null() { 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( dc_saxparser_init(
&mut saxparser, &mut saxparser,
&mut kml as *mut dc_kml_t as *mut libc::c_void, &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 && 0. != (*kml).curr.longitude
{ {
let location = (*kml).curr.clone(); let location = (*kml).curr.clone();
dc_array_add_ptr( (*(*kml).locations).add_location(location);
(*kml).locations,
Box::into_raw(Box::new(location)) as *mut libc::c_void,
);
} }
(*kml).tag = 0 (*kml).tag = 0
}; };