Use Vec to store dc_array_t data

This commit is contained in:
Alexander Krotov
2019-07-22 03:30:31 +03:00
parent 252697b174
commit e15e3a1e84
2 changed files with 64 additions and 122 deletions

View File

@@ -6,23 +6,19 @@ const DC_ARRAY_MAGIC: uint32_t = 0x000a11aa;
const DC_ARRAY_LOCATIONS: libc::c_int = 1; const DC_ARRAY_LOCATIONS: libc::c_int = 1;
/* * the structure behind dc_array_t */ /* * the structure behind dc_array_t */
#[derive(Copy, Clone)] #[derive(Clone)]
pub struct dc_array_t { pub struct dc_array_t {
pub magic: uint32_t, pub magic: uint32_t,
pub allocated: size_t,
pub count: size_t,
pub type_0: libc::c_int, pub type_0: libc::c_int,
pub array: *mut uintptr_t, pub array: Vec<uintptr_t>,
} }
impl dc_array_t { impl dc_array_t {
pub fn new() -> Self { pub fn new(capacity: usize) -> Self {
dc_array_t { dc_array_t {
magic: DC_ARRAY_MAGIC, magic: DC_ARRAY_MAGIC,
allocated: 0,
count: 0,
type_0: 0, type_0: 0,
array: 0 as *mut uintptr_t, array: Vec::with_capacity(capacity),
} }
} }
@@ -46,7 +42,6 @@ pub unsafe fn dc_array_unref(mut array: *mut dc_array_t) {
if (*array).type_0 == DC_ARRAY_LOCATIONS { if (*array).type_0 == DC_ARRAY_LOCATIONS {
dc_array_free_ptr(array); dc_array_free_ptr(array);
} }
free((*array).array as *mut libc::c_void);
(*array).magic = 0i32 as uint32_t; (*array).magic = 0i32 as uint32_t;
Box::from_raw(array); Box::from_raw(array);
} }
@@ -55,31 +50,21 @@ pub unsafe fn dc_array_free_ptr(array: *mut dc_array_t) {
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC {
return; return;
} }
for i in 0..(*array).count { for i in 0..(*array).array.len() {
if (*array).type_0 == DC_ARRAY_LOCATIONS { if (*array).type_0 == DC_ARRAY_LOCATIONS {
Box::from_raw(*(*array).array.offset(i as isize) as *mut dc_location); Box::from_raw((*array).array[i] as *mut dc_location);
} else { } else {
free(*(*array).array.offset(i as isize) as *mut libc::c_void); free((*array).array[i] as *mut libc::c_void);
} }
*(*array).array.offset(i as isize) = 0i32 as uintptr_t; (*array).array[i] = 0i32 as uintptr_t;
} }
} }
pub unsafe fn dc_array_add_uint(mut array: *mut dc_array_t, item: uintptr_t) { pub unsafe fn dc_array_add_uint(array: *mut dc_array_t, item: uintptr_t) {
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC {
return; return;
} }
if (*array).count == (*array).allocated { (*array).array.push(item);
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::<uintptr_t>()),
) as *mut uintptr_t;
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) {
@@ -94,127 +79,127 @@ 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() || (*array).magic != DC_ARRAY_MAGIC {
return 0i32 as size_t; return 0i32 as size_t;
} }
(*array).count (*array).array.len()
} }
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() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).array.len() {
return 0i32 as uintptr_t; return 0i32 as uintptr_t;
} }
*(*array).array.offset(index as isize) (*array).array[index]
} }
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() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).array.len() {
return 0i32 as uint32_t; return 0i32 as uint32_t;
} }
if (*array).type_0 == DC_ARRAY_LOCATIONS { if (*array).type_0 == DC_ARRAY_LOCATIONS {
return (*(*(*array).array.offset(index as isize) as *mut dc_location)).location_id; return (*((*array).array[index] as *mut dc_location)).location_id;
} }
*(*array).array.offset(index as isize) as uint32_t (*array).array[index] 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() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).array.len() {
return 0 as *mut libc::c_void; return 0 as *mut libc::c_void;
} }
*(*array).array.offset(index as isize) as *mut libc::c_void (*array).array[index] 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()
|| (*array).magic != DC_ARRAY_MAGIC || (*array).magic != DC_ARRAY_MAGIC
|| index >= (*array).count || index >= (*array).array.len()
|| (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).type_0 != DC_ARRAY_LOCATIONS
|| *(*array).array.offset(index as isize) == 0 || (*array).array[index] == 0
{ {
return 0i32 as libc::c_double; return 0i32 as libc::c_double;
} }
(*(*(*array).array.offset(index as isize) as *mut dc_location)).latitude (*((*array).array[index] 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()
|| (*array).magic != DC_ARRAY_MAGIC || (*array).magic != DC_ARRAY_MAGIC
|| index >= (*array).count || index >= (*array).array.len()
|| (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).type_0 != DC_ARRAY_LOCATIONS
|| *(*array).array.offset(index as isize) == 0 || (*array).array[index] == 0
{ {
return 0i32 as libc::c_double; return 0i32 as libc::c_double;
} }
(*(*(*array).array.offset(index as isize) as *mut dc_location)).longitude (*((*array).array[index] 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()
|| (*array).magic != DC_ARRAY_MAGIC || (*array).magic != DC_ARRAY_MAGIC
|| index >= (*array).count || index >= (*array).array.len()
|| (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).type_0 != DC_ARRAY_LOCATIONS
|| *(*array).array.offset(index as isize) == 0 || (*array).array[index] == 0
{ {
return 0i32 as libc::c_double; return 0i32 as libc::c_double;
} }
(*(*(*array).array.offset(index as isize) as *mut dc_location)).accuracy (*((*array).array[index] 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()
|| (*array).magic != DC_ARRAY_MAGIC || (*array).magic != DC_ARRAY_MAGIC
|| index >= (*array).count || index >= (*array).array.len()
|| (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).type_0 != DC_ARRAY_LOCATIONS
|| *(*array).array.offset(index as isize) == 0 || (*array).array[index] == 0
{ {
return 0; return 0;
} }
(*(*(*array).array.offset(index as isize) as *mut dc_location)).timestamp (*((*array).array[index] 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()
|| (*array).magic != DC_ARRAY_MAGIC || (*array).magic != DC_ARRAY_MAGIC
|| index >= (*array).count || index >= (*array).array.len()
|| (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).type_0 != DC_ARRAY_LOCATIONS
|| *(*array).array.offset(index as isize) == 0 || (*array).array[index] == 0
{ {
return 0i32 as uint32_t; return 0i32 as uint32_t;
} }
(*(*(*array).array.offset(index as isize) as *mut dc_location)).chat_id (*((*array).array[index] 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()
|| (*array).magic != DC_ARRAY_MAGIC || (*array).magic != DC_ARRAY_MAGIC
|| index >= (*array).count || index >= (*array).array.len()
|| (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).type_0 != DC_ARRAY_LOCATIONS
|| *(*array).array.offset(index as isize) == 0 || (*array).array[index] == 0
{ {
return 0i32 as uint32_t; return 0i32 as uint32_t;
} }
(*(*(*array).array.offset(index as isize) as *mut dc_location)).contact_id (*((*array).array[index] 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()
|| (*array).magic != DC_ARRAY_MAGIC || (*array).magic != DC_ARRAY_MAGIC
|| index >= (*array).count || index >= (*array).array.len()
|| (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).type_0 != DC_ARRAY_LOCATIONS
|| *(*array).array.offset(index as isize) == 0 || (*array).array[index] == 0
{ {
return 0i32 as uint32_t; return 0i32 as uint32_t;
} }
(*(*(*array).array.offset(index as isize) as *mut dc_location)).msg_id (*((*array).array[index] 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()
|| (*array).magic != DC_ARRAY_MAGIC || (*array).magic != DC_ARRAY_MAGIC
|| index >= (*array).count || index >= (*array).array.len()
|| (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).type_0 != DC_ARRAY_LOCATIONS
|| *(*array).array.offset(index as isize) == 0 || (*array).array[index] == 0
{ {
return 0 as *mut libc::c_char; return 0 as *mut libc::c_char;
} }
if let Some(s) = &(*(*(*array).array.offset(index as isize) as *mut dc_location)).marker { if let Some(s) = &(*((*array).array[index] as *mut dc_location)).marker {
to_cstring(s) to_cstring(s)
} else { } else {
std::ptr::null_mut() std::ptr::null_mut()
@@ -234,14 +219,14 @@ pub unsafe fn dc_array_get_marker(array: *const dc_array_t, index: size_t) -> *m
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()
|| (*array).magic != DC_ARRAY_MAGIC || (*array).magic != DC_ARRAY_MAGIC
|| index >= (*array).count || index >= (*array).array.len()
|| (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).type_0 != DC_ARRAY_LOCATIONS
|| *(*array).array.offset(index as isize) == 0 || (*array).array[index] == 0
{ {
return 0; return 0;
} }
(*(*(*array).array.offset(index as isize) as *mut dc_location)).independent as libc::c_int (*((*array).array[index] as *mut dc_location)).independent as libc::c_int
} }
pub unsafe fn dc_array_search_id( pub unsafe fn dc_array_search_id(
@@ -252,9 +237,8 @@ pub unsafe fn dc_array_search_id(
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC {
return false; return false;
} }
let data: *mut uintptr_t = (*array).array; for i in 0..(*array).array.len() {
for i in 0..(*array).count { if (*array).array[i] == needle as size_t {
if *data.offset(i as isize) == needle as size_t {
if !ret_index.is_null() { if !ret_index.is_null() {
*ret_index = i *ret_index = i
} }
@@ -268,7 +252,7 @@ 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() || (*array).magic != DC_ARRAY_MAGIC {
return 0 as *const uintptr_t; return 0 as *const uintptr_t;
} }
(*array).array (*array).array.as_ptr()
} }
pub unsafe fn dc_array_new(initsize: size_t) -> *mut dc_array_t { pub unsafe fn dc_array_new(initsize: size_t) -> *mut dc_array_t {
@@ -276,27 +260,17 @@ pub unsafe fn dc_array_new(initsize: size_t) -> *mut dc_array_t {
} }
pub unsafe fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut dc_array_t { pub unsafe fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut dc_array_t {
let mut array = dc_array_t::new(); let capacity = if initsize < 1 { 1 } else { initsize as usize };
let mut array = dc_array_t::new(capacity);
array.allocated = if initsize < 1 { 1 } else { initsize };
array.type_0 = type_0; 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.as_ptr() array.as_ptr()
} }
pub unsafe fn dc_array_empty(mut array: *mut dc_array_t) { pub unsafe fn dc_array_empty(array: *mut dc_array_t) {
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC {
return; return;
} }
(*array).count = 0i32 as size_t; (*array).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 {
@@ -304,40 +278,16 @@ pub unsafe fn dc_array_duplicate(array: *const dc_array_t) -> *mut dc_array_t {
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC {
return 0 as *mut dc_array_t; return 0 as *mut dc_array_t;
} }
ret = dc_array_new((*array).allocated); ret = dc_array_new(1);
(*ret).count = (*array).count; (*ret).array = (*array).array.clone();
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 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).magic != DC_ARRAY_MAGIC || (*array).array.len() <= 1 {
return; return;
} }
qsort( (*array).array.sort();
(*array).array as *mut libc::c_void,
(*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 {
0i32
};
} }
pub unsafe fn dc_array_get_string( pub unsafe fn dc_array_get_string(
@@ -347,14 +297,12 @@ pub unsafe fn dc_array_get_string(
if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || sep.is_null() { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || 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; let cnt = (*array).array.len();
let slice = std::slice::from_raw_parts((*array).array, cnt);
let sep = as_str(sep); let sep = as_str(sep);
let res = slice let res = (*array).array.iter().enumerate().fold(
.iter() String::with_capacity(2 * cnt),
.enumerate() |mut res, (i, n)| {
.fold(String::with_capacity(2 * cnt), |mut res, (i, n)| {
if i == 0 { if i == 0 {
res += &n.to_string(); res += &n.to_string();
} else { } else {

View File

@@ -2168,11 +2168,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).array.is_empty() {
contact = dc_get_contact( contact = dc_get_contact((*chat).context, (*contacts).array[0] as uint32_t);
(*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 +2189,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).array.is_empty() {
contact = dc_get_contact( contact = dc_get_contact((*chat).context, (*contacts).array[0] as uint32_t);
(*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 {