From a0594338b22b7dbac1220ac8c2eea361e337c2a9 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 22 Jul 2019 00:01:46 +0300 Subject: [PATCH 01/30] Remove repr(C) from dc_array_t All members of dc_array_t structure are private, C code does not need to interact with them. --- src/dc_array.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index f62b2ee3f..3d15ef356 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -7,7 +7,6 @@ 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, From 7cba2b3f66471d74d7f6adb4846869de89f69cb5 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 02:33:00 +0300 Subject: [PATCH 02/30] Remove unused dc_array_sort_strings --- src/dc_array.rs | 56 +------------------------------------------------ 1 file changed, 1 insertion(+), 55 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 3d15ef356..b9e13bad8 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -1,7 +1,6 @@ use crate::dc_location::dc_location; use crate::dc_tools::*; use crate::types::*; -use crate::x::*; const DC_ARRAY_MAGIC: uint32_t = 0x000a11aa; @@ -328,28 +327,6 @@ unsafe extern "C" fn cmp_intptr_t(p1: *const libc::c_void, p2: *const libc::c_vo }; } -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( array: *const dc_array_t, sep: *const libc::c_char, @@ -379,6 +356,7 @@ pub unsafe fn dc_array_get_string( #[cfg(test)] mod tests { use super::*; + use crate::x::*; use std::ffi::CStr; #[test] @@ -428,38 +406,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); } } From f0ae5fcd7c9bb6d6c8f85cdc5889b1534d97ef73 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 22 Jul 2019 00:14:15 +0300 Subject: [PATCH 03/30] Add DC_ARRAY_LOCATIONS constant --- src/dc_array.rs | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index b9e13bad8..681c6938c 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -3,6 +3,7 @@ use crate::dc_tools::*; use crate::types::*; const DC_ARRAY_MAGIC: uint32_t = 0x000a11aa; +const DC_ARRAY_LOCATIONS: libc::c_int = 1; /* * the structure behind dc_array_t */ #[derive(Copy, Clone)] @@ -26,7 +27,7 @@ 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 { + if (*array).type_0 == DC_ARRAY_LOCATIONS { dc_array_free_ptr(array); } free((*array).array as *mut libc::c_void); @@ -40,7 +41,11 @@ pub unsafe fn dc_array_free_ptr(array: *mut dc_array_t) { } 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); + if (*array).type_0 == DC_ARRAY_LOCATIONS { + Box::from_raw(*(*array).array.offset(i as isize) as *mut dc_location); + } else { + free(*(*array).array.offset(i as isize) as *mut libc::c_void); + } *(*array).array.offset(i as isize) = 0i32 as uintptr_t; i = i.wrapping_add(1) } @@ -89,7 +94,7 @@ pub unsafe fn dc_array_get_id(array: *const dc_array_t, index: size_t) -> uint32 if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count { return 0i32 as uint32_t; } - if (*array).type_0 == 1i32 { + if (*array).type_0 == DC_ARRAY_LOCATIONS { return (*(*(*array).array.offset(index as isize) as *mut dc_location)).location_id; } *(*array).array.offset(index as isize) as uint32_t @@ -106,7 +111,7 @@ pub unsafe fn dc_array_get_latitude(array: *const dc_array_t, index: size_t) -> if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count - || (*array).type_0 != 1i32 + || (*array).type_0 != DC_ARRAY_LOCATIONS || *(*array).array.offset(index as isize) == 0 { return 0i32 as libc::c_double; @@ -118,7 +123,7 @@ pub unsafe fn dc_array_get_longitude(array: *const dc_array_t, index: size_t) -> if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count - || (*array).type_0 != 1i32 + || (*array).type_0 != DC_ARRAY_LOCATIONS || *(*array).array.offset(index as isize) == 0 { return 0i32 as libc::c_double; @@ -130,7 +135,7 @@ pub unsafe fn dc_array_get_accuracy(array: *const dc_array_t, index: size_t) -> if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count - || (*array).type_0 != 1i32 + || (*array).type_0 != DC_ARRAY_LOCATIONS || *(*array).array.offset(index as isize) == 0 { return 0i32 as libc::c_double; @@ -142,7 +147,7 @@ pub unsafe fn dc_array_get_timestamp(array: *const dc_array_t, index: size_t) -> if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count - || (*array).type_0 != 1i32 + || (*array).type_0 != DC_ARRAY_LOCATIONS || *(*array).array.offset(index as isize) == 0 { return 0; @@ -154,7 +159,7 @@ pub unsafe fn dc_array_get_chat_id(array: *const dc_array_t, index: size_t) -> u if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count - || (*array).type_0 != 1i32 + || (*array).type_0 != DC_ARRAY_LOCATIONS || *(*array).array.offset(index as isize) == 0 { return 0i32 as uint32_t; @@ -166,7 +171,7 @@ pub unsafe fn dc_array_get_contact_id(array: *const dc_array_t, index: size_t) - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count - || (*array).type_0 != 1i32 + || (*array).type_0 != DC_ARRAY_LOCATIONS || *(*array).array.offset(index as isize) == 0 { return 0i32 as uint32_t; @@ -178,7 +183,7 @@ pub unsafe fn dc_array_get_msg_id(array: *const dc_array_t, index: size_t) -> ui if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count - || (*array).type_0 != 1i32 + || (*array).type_0 != DC_ARRAY_LOCATIONS || *(*array).array.offset(index as isize) == 0 { return 0i32 as uint32_t; @@ -190,7 +195,7 @@ pub unsafe fn dc_array_get_marker(array: *const dc_array_t, index: size_t) -> *m if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count - || (*array).type_0 != 1i32 + || (*array).type_0 != DC_ARRAY_LOCATIONS || *(*array).array.offset(index as isize) == 0 { return 0 as *mut libc::c_char; @@ -216,7 +221,7 @@ pub unsafe fn dc_array_is_independent(array: *const dc_array_t, index: size_t) - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).count - || (*array).type_0 != 1i32 + || (*array).type_0 != DC_ARRAY_LOCATIONS || *(*array).array.offset(index as isize) == 0 { return 0; From 7585dc49e380dc6f5ea2bc21bf48d4c365967c45 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 22 Jul 2019 01:24:19 +0300 Subject: [PATCH 04/30] Replace C loop with Rust loop in dc_array_free_ptr --- src/dc_array.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 681c6938c..d52124ddb 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -39,15 +39,13 @@ pub unsafe fn dc_array_free_ptr(array: *mut dc_array_t) { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { return; } - let mut i: size_t = 0i32 as size_t; - while i < (*array).count { + for i in 0..(*array).count { if (*array).type_0 == DC_ARRAY_LOCATIONS { Box::from_raw(*(*array).array.offset(i as isize) as *mut dc_location); } else { free(*(*array).array.offset(i as isize) as *mut libc::c_void); } *(*array).array.offset(i as isize) = 0i32 as uintptr_t; - i = i.wrapping_add(1) } } From 7764ab3ff31c80d99955b15b055b7ad26e6e6d13 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 22 Jul 2019 01:26:07 +0300 Subject: [PATCH 05/30] Replace C loop with Rust loop in dc_array_search_id --- src/dc_array.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index d52124ddb..2420e08c9 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -237,16 +237,13 @@ pub unsafe fn dc_array_search_id( return false; } let data: *mut uintptr_t = (*array).array; - let mut i: size_t = 0; - let cnt: size_t = (*array).count; - while i < cnt { + for i in 0..(*array).count { 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) } false } From 252697b1746b4800639a343a5f0a2012cb3f9718 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 22 Jul 2019 02:46:58 +0300 Subject: [PATCH 06/30] Implement dc_array_t::new() and use Box to allocate dc_array_t --- src/dc_array.rs | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 2420e08c9..46ded0c27 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -15,6 +15,22 @@ pub struct dc_array_t { pub array: *mut uintptr_t, } +impl dc_array_t { + pub fn new() -> Self { + dc_array_t { + magic: DC_ARRAY_MAGIC, + allocated: 0, + count: 0, + type_0: 0, + array: 0 as *mut uintptr_t, + } + } + + pub fn as_ptr(self) -> *mut Self { + Box::into_raw(Box::new(self)) + } +} + /** * @class dc_array_t * @@ -32,7 +48,7 @@ pub unsafe fn dc_array_unref(mut array: *mut dc_array_t) { } free((*array).array as *mut libc::c_void); (*array).magic = 0i32 as uint32_t; - free(array as *mut libc::c_void); + Box::from_raw(array); } pub unsafe fn dc_array_free_ptr(array: *mut dc_array_t) { @@ -260,23 +276,20 @@ 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 { - let mut array: *mut dc_array_t; - array = calloc(1, ::std::mem::size_of::()) as *mut dc_array_t; - assert!(!array.is_null()); + let mut array = dc_array_t::new(); - (*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) + 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() { + if array.array.is_null() { exit(48i32); } - array + + array.as_ptr() } pub unsafe fn dc_array_empty(mut array: *mut dc_array_t) { From e15e3a1e84d03945cde5c77a9da4682614b29678 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 22 Jul 2019 03:30:31 +0300 Subject: [PATCH 07/30] Use Vec to store dc_array_t data --- src/dc_array.rs | 172 +++++++++++++++++------------------------------- src/dc_chat.rs | 14 ++-- 2 files changed, 64 insertions(+), 122 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 46ded0c27..d850c0533 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -6,23 +6,19 @@ const DC_ARRAY_MAGIC: uint32_t = 0x000a11aa; const DC_ARRAY_LOCATIONS: libc::c_int = 1; /* * the structure behind dc_array_t */ -#[derive(Copy, Clone)] +#[derive(Clone)] 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, + pub array: Vec, } impl dc_array_t { - pub fn new() -> Self { + pub fn new(capacity: usize) -> Self { dc_array_t { magic: DC_ARRAY_MAGIC, - allocated: 0, - count: 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 { dc_array_free_ptr(array); } - free((*array).array as *mut libc::c_void); (*array).magic = 0i32 as uint32_t; 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 { return; } - for i in 0..(*array).count { + for i in 0..(*array).array.len() { 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 { - 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 { 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 - } - *(*array).array.offset((*array).count as isize) = item; - (*array).count = (*array).count.wrapping_add(1); + (*array).array.push(item); } 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 { 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 { - 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; } - *(*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 { - 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; } 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 { - 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; } - *(*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 { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count + || index >= (*array).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS - || *(*array).array.offset(index as isize) == 0 + || (*array).array[index] == 0 { 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 { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count + || index >= (*array).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS - || *(*array).array.offset(index as isize) == 0 + || (*array).array[index] == 0 { 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 { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count + || index >= (*array).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS - || *(*array).array.offset(index as isize) == 0 + || (*array).array[index] == 0 { 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 { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count + || index >= (*array).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS - || *(*array).array.offset(index as isize) == 0 + || (*array).array[index] == 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 { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count + || index >= (*array).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS - || *(*array).array.offset(index as isize) == 0 + || (*array).array[index] == 0 { 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 { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count + || index >= (*array).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS - || *(*array).array.offset(index as isize) == 0 + || (*array).array[index] == 0 { 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 { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count + || index >= (*array).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS - || *(*array).array.offset(index as isize) == 0 + || (*array).array[index] == 0 { 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 { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count + || index >= (*array).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS - || *(*array).array.offset(index as isize) == 0 + || (*array).array[index] == 0 { 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) } else { 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 { if array.is_null() || (*array).magic != DC_ARRAY_MAGIC - || index >= (*array).count + || index >= (*array).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS - || *(*array).array.offset(index as isize) == 0 + || (*array).array[index] == 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( @@ -252,9 +237,8 @@ pub unsafe fn dc_array_search_id( if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { return false; } - let data: *mut uintptr_t = (*array).array; - for i in 0..(*array).count { - if *data.offset(i as isize) == needle as size_t { + for i in 0..(*array).array.len() { + if (*array).array[i] == needle as size_t { if !ret_index.is_null() { *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 { 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 { @@ -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 { - let mut array = dc_array_t::new(); - - array.allocated = if initsize < 1 { 1 } else { initsize }; + let capacity = if initsize < 1 { 1 } else { initsize as usize }; + let mut array = dc_array_t::new(capacity); 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); - } - 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 { 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 { @@ -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 { return 0 as *mut dc_array_t; } - 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 = dc_array_new(1); + (*ret).array = (*array).array.clone(); 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).magic != DC_ARRAY_MAGIC || (*array).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 - } else { - 0i32 - }; + (*array).array.sort(); } 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() { 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 cnt = (*array).array.len(); let sep = as_str(sep); - let res = slice - .iter() - .enumerate() - .fold(String::with_capacity(2 * cnt), |mut res, (i, n)| { + let res = (*array).array.iter().enumerate().fold( + String::with_capacity(2 * cnt), + |mut res, (i, n)| { if i == 0 { res += &n.to_string(); } else { diff --git a/src/dc_chat.rs b/src/dc_chat.rs index 8f7ac8ddf..aed692a96 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -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) } 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).array.is_empty() { + contact = dc_get_contact((*chat).context, (*contacts).array[0] as uint32_t); 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).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).array.is_empty() { + contact = dc_get_contact((*chat).context, (*contacts).array[0] as uint32_t); color = dc_str_to_color((*contact).addr) as uint32_t } } else { From 1dfad65afd91f901b4efff4771eb4d6ea6558fce Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 22 Jul 2019 13:39:37 +0300 Subject: [PATCH 08/30] dc_array.rs: remove magic field It was always set to DC_ARRAY_MAGIC, except immediately before freeing the memory. --- src/dc_array.rs | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index d850c0533..0545dc95f 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -2,13 +2,11 @@ use crate::dc_location::dc_location; use crate::dc_tools::*; use crate::types::*; -const DC_ARRAY_MAGIC: uint32_t = 0x000a11aa; const DC_ARRAY_LOCATIONS: libc::c_int = 1; /* * the structure behind dc_array_t */ #[derive(Clone)] pub struct dc_array_t { - pub magic: uint32_t, pub type_0: libc::c_int, pub array: Vec, } @@ -16,7 +14,6 @@ pub struct dc_array_t { impl dc_array_t { pub fn new(capacity: usize) -> Self { dc_array_t { - magic: DC_ARRAY_MAGIC, type_0: 0, array: Vec::with_capacity(capacity), } @@ -35,19 +32,18 @@ impl dc_array_t { * 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 { +pub unsafe fn dc_array_unref(array: *mut dc_array_t) { + if array.is_null() { return; } if (*array).type_0 == DC_ARRAY_LOCATIONS { dc_array_free_ptr(array); } - (*array).magic = 0i32 as uint32_t; Box::from_raw(array); } 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() { return; } for i in 0..(*array).array.len() { @@ -61,7 +57,7 @@ pub unsafe fn dc_array_free_ptr(array: *mut dc_array_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() { return; } (*array).array.push(item); @@ -76,21 +72,21 @@ 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 { + if array.is_null() { return 0i32 as size_t; } (*array).array.len() } 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).array.len() { + if array.is_null() || index >= (*array).array.len() { return 0i32 as uintptr_t; } (*array).array[index] } 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).array.len() { + if array.is_null() || index >= (*array).array.len() { return 0i32 as uint32_t; } if (*array).type_0 == DC_ARRAY_LOCATIONS { @@ -100,7 +96,7 @@ pub unsafe fn dc_array_get_id(array: *const dc_array_t, index: size_t) -> uint32 } 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).array.len() { + if array.is_null() || index >= (*array).array.len() { return 0 as *mut libc::c_void; } (*array).array[index] as *mut libc::c_void @@ -108,7 +104,6 @@ pub unsafe fn dc_array_get_ptr(array: *const dc_array_t, index: size_t) -> *mut 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).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 @@ -120,7 +115,6 @@ pub unsafe fn dc_array_get_latitude(array: *const dc_array_t, index: size_t) -> 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).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 @@ -132,7 +126,6 @@ pub unsafe fn dc_array_get_longitude(array: *const dc_array_t, index: size_t) -> 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).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 @@ -144,7 +137,6 @@ pub unsafe fn dc_array_get_accuracy(array: *const dc_array_t, index: size_t) -> 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).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 @@ -156,7 +148,6 @@ pub unsafe fn dc_array_get_timestamp(array: *const dc_array_t, index: size_t) -> 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).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 @@ -168,7 +159,6 @@ pub unsafe fn dc_array_get_chat_id(array: *const dc_array_t, index: size_t) -> u 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).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 @@ -180,7 +170,6 @@ pub unsafe fn dc_array_get_contact_id(array: *const dc_array_t, index: size_t) - 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).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 @@ -192,7 +181,6 @@ pub unsafe fn dc_array_get_msg_id(array: *const dc_array_t, index: size_t) -> ui 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).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 @@ -218,7 +206,6 @@ 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 { if array.is_null() - || (*array).magic != DC_ARRAY_MAGIC || index >= (*array).array.len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 @@ -234,7 +221,7 @@ 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; } for i in 0..(*array).array.len() { @@ -249,7 +236,7 @@ pub unsafe fn dc_array_search_id( } 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.as_ptr() @@ -267,7 +254,7 @@ pub unsafe fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut } pub unsafe fn dc_array_empty(array: *mut dc_array_t) { - if array.is_null() || (*array).magic != DC_ARRAY_MAGIC { + if array.is_null() { return; } (*array).array.clear(); @@ -275,7 +262,7 @@ pub unsafe fn dc_array_empty(array: *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() || (*array).magic != DC_ARRAY_MAGIC { + if array.is_null() { return 0 as *mut dc_array_t; } ret = dc_array_new(1); @@ -284,7 +271,7 @@ pub unsafe fn dc_array_duplicate(array: *const dc_array_t) -> *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).array.len() <= 1 { + if array.is_null() || (*array).array.len() <= 1 { return; } (*array).array.sort(); @@ -294,7 +281,7 @@ 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).array.len(); From 05aca2c529994068ce4c93b2716aadf67615aa88 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 22 Jul 2019 14:00:00 +0300 Subject: [PATCH 09/30] Make dc_array_new and dc_array_new_typed safe Just like Box::into_raw, these functions are safe, even though the caller is responsible for the allocated structure. --- src/context.rs | 4 ++-- src/dc_array.rs | 4 ++-- src/dc_chat.rs | 4 ++-- src/dc_contact.rs | 4 ++-- src/dc_location.rs | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/context.rs b/src/context.rs index 4d52d658b..c61fee72c 100644 --- a/src/context.rs +++ b/src/context.rs @@ -521,7 +521,7 @@ 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 ret = dc_array_new(128 as size_t); for row in rows { let id = row?; @@ -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 ret = dc_array_new(100 as size_t); let success = context .sql diff --git a/src/dc_array.rs b/src/dc_array.rs index 0545dc95f..4c09c183e 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -242,11 +242,11 @@ pub unsafe fn dc_array_get_raw(array: *const dc_array_t) -> *const uintptr_t { (*array).array.as_ptr() } -pub unsafe fn dc_array_new(initsize: size_t) -> *mut dc_array_t { +pub 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 { +pub fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut dc_array_t { let capacity = if initsize < 1 { 1 } else { initsize as usize }; let mut array = dc_array_t::new(capacity); array.type_0 = type_0; diff --git a/src/dc_chat.rs b/src/dc_chat.rs index aed692a96..59c4b2310 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -1285,7 +1285,7 @@ pub fn dc_get_chat_media( ], |row| row.get::<_, i32>(0), |ids| { - let ret = unsafe { dc_array_new(100) }; + let ret = dc_array_new(100); for id in ids { unsafe { dc_array_add_id(ret, id? as u32) }; } @@ -1458,7 +1458,7 @@ 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 ret = dc_array_new(100); for id in ids { unsafe { dc_array_add_id(ret, id? as u32) }; diff --git a/src/dc_contact.rs b/src/dc_contact.rs index 4a3a62afd..3bb956caa 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 ret = dc_array_new(100); if (listflags & DC_GCL_VERIFIED_ONLY) > 0 || !query.is_null() { let s3strLikeCmd = format!("%{}%", if !query.is_null() { as_str(query) } else { "" }); @@ -629,7 +629,7 @@ 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 ret = dc_array_new(100); for id in ids { unsafe { dc_array_add_id(ret, id? as u32) }; diff --git a/src/dc_location.rs b/src/dc_location.rs index 2a89d84ab..de15713e7 100644 --- a/src/dc_location.rs +++ b/src/dc_location.rs @@ -247,7 +247,7 @@ pub fn dc_get_locations( Ok(loc) }, |locations| { - let ret = unsafe { dc_array_new_typed(1, 500) }; + let ret = dc_array_new_typed(1, 500); for location in locations { unsafe { From a323fe68a60674ff26da0e45dbcc19fd1281d40b Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 22 Jul 2019 15:05:23 +0300 Subject: [PATCH 10/30] Simplify dc_array_duplicate --- src/dc_array.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 4c09c183e..2a5d240fc 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -261,13 +261,11 @@ pub unsafe fn dc_array_empty(array: *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() { - return 0 as *mut dc_array_t; + std::ptr::null_mut() + } else { + (*array).clone().as_ptr() } - ret = dc_array_new(1); - (*ret).array = (*array).array.clone(); - ret } pub unsafe fn dc_array_sort_ids(array: *mut dc_array_t) { From 85dfd65e48bdb9b7990e2bf83f94684738d26771 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 00:09:10 +0300 Subject: [PATCH 11/30] Simplify dc_array_get_string --- src/dc_array.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 2a5d240fc..a9a8b6967 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -285,17 +285,18 @@ pub unsafe fn dc_array_get_string( let cnt = (*array).array.len(); let sep = as_str(sep); - let res = (*array).array.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 - }); + let res = + (*array) + .array + .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) } From e796a4c4386b7b3af074d91de0eb6e344783dd61 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 00:11:00 +0300 Subject: [PATCH 12/30] Move dc_array_add_{uint,id} implementations into dc_array_t --- src/dc_array.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index a9a8b6967..93e5dbe7f 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -22,6 +22,14 @@ impl dc_array_t { pub fn as_ptr(self) -> *mut Self { Box::into_raw(Box::new(self)) } + + pub fn add_uint(&mut self, item: uintptr_t) { + self.array.push(item); + } + + pub fn add_id(&mut self, item: uint32_t) { + self.add_uint(item as uintptr_t); + } } /** @@ -57,14 +65,15 @@ pub unsafe fn dc_array_free_ptr(array: *mut dc_array_t) { } pub unsafe fn dc_array_add_uint(array: *mut dc_array_t, item: uintptr_t) { - if array.is_null() { - return; + if !array.is_null() { + (*array).add_uint(item); } - (*array).array.push(item); } 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) { From 1f63753a8b21d4d905642f642b147bf4e37f37b5 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 00:11:35 +0300 Subject: [PATCH 13/30] Simplify dc_array_search_id --- src/dc_array.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 93e5dbe7f..3991e3fd1 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -233,8 +233,8 @@ pub unsafe fn dc_array_search_id( if array.is_null() { return false; } - for i in 0..(*array).array.len() { - if (*array).array[i] == needle as size_t { + for (i, &u) in (*array).array.iter().enumerate() { + if u == needle as size_t { if !ret_index.is_null() { *ret_index = i } From 8d43ad48097e10e1011a63e89a18e1381f69a183 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 00:12:23 +0300 Subject: [PATCH 14/30] Construct dc_array_t id arrays using safe methods --- src/context.rs | 15 ++++++--------- src/dc_chat.rs | 28 ++++++++++++---------------- src/dc_contact.rs | 16 ++++++++-------- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/context.rs b/src/context.rs index c61fee72c..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 = 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 = 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_chat.rs b/src/dc_chat.rs index 59c4b2310..2668b08a3 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 = 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 = 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_contact.rs b/src/dc_contact.rs index 3bb956caa..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 = 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 = 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()) From f3eea419148d733ffa211cb123c064e018b972c3 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 00:41:51 +0300 Subject: [PATCH 15/30] Reimplement dc_array_new without dc_array_new_typed --- src/dc_array.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 3991e3fd1..66bdac279 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -252,7 +252,7 @@ pub unsafe fn dc_array_get_raw(array: *const dc_array_t) -> *const uintptr_t { } pub fn dc_array_new(initsize: size_t) -> *mut dc_array_t { - dc_array_new_typed(0, initsize) + dc_array_t::new(initsize).as_ptr() } pub fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut dc_array_t { From c7a6b3caae3131fe8d1a3373cf300976db4ef8df Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 00:48:11 +0300 Subject: [PATCH 16/30] Remove unnecessary check in dc_array_new_typed Allocating Vec with 0 capacity is correct. --- src/dc_array.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 66bdac279..7bff7823f 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -256,8 +256,7 @@ pub fn dc_array_new(initsize: size_t) -> *mut dc_array_t { } pub fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut dc_array_t { - let capacity = if initsize < 1 { 1 } else { initsize as usize }; - let mut array = dc_array_t::new(capacity); + let mut array = dc_array_t::new(initsize); array.type_0 = type_0; array.as_ptr() } From dfd43cbb97250d07a90b0f3ac6b836a0ca3cbb17 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 00:58:57 +0300 Subject: [PATCH 17/30] Rename dc_array_new_typed into dc_array_new_locations dc_array_new_typed is only used internally, so we can change its API. --- src/dc_array.rs | 14 ++++++++++---- src/dc_location.rs | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 7bff7823f..a378e4740 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -19,6 +19,14 @@ impl dc_array_t { } } + /// Constructs a new, empty `dc_array_t` holding locations with specified `capacity`. + pub fn new_locations(capacity: usize) -> Self { + dc_array_t { + type_0: DC_ARRAY_LOCATIONS, + array: Vec::with_capacity(capacity), + } + } + pub fn as_ptr(self) -> *mut Self { Box::into_raw(Box::new(self)) } @@ -255,10 +263,8 @@ pub fn dc_array_new(initsize: size_t) -> *mut dc_array_t { dc_array_t::new(initsize).as_ptr() } -pub fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut dc_array_t { - let mut array = dc_array_t::new(initsize); - array.type_0 = type_0; - array.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) { diff --git a/src/dc_location.rs b/src/dc_location.rs index de15713e7..b529ad123 100644 --- a/src/dc_location.rs +++ b/src/dc_location.rs @@ -247,7 +247,7 @@ pub fn dc_get_locations( Ok(loc) }, |locations| { - let ret = dc_array_new_typed(1, 500); + let ret = dc_array_new_locations(500); for location in locations { unsafe { @@ -501,7 +501,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, From 1e91f6a2048d0fb633c5033341218383c28ebc8d Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 01:07:49 +0300 Subject: [PATCH 18/30] Merge dc_array_free_ptr into dc_array_unref --- src/dc_array.rs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index a378e4740..259df106d 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -53,25 +53,13 @@ pub unsafe fn dc_array_unref(array: *mut dc_array_t) { return; } if (*array).type_0 == DC_ARRAY_LOCATIONS { - dc_array_free_ptr(array); + for &e in (*array).array.iter() { + Box::from_raw(e as *mut dc_location); + } } Box::from_raw(array); } -pub unsafe fn dc_array_free_ptr(array: *mut dc_array_t) { - if array.is_null() { - return; - } - for i in 0..(*array).array.len() { - if (*array).type_0 == DC_ARRAY_LOCATIONS { - Box::from_raw((*array).array[i] as *mut dc_location); - } else { - free((*array).array[i] as *mut libc::c_void); - } - (*array).array[i] = 0i32 as uintptr_t; - } -} - pub unsafe fn dc_array_add_uint(array: *mut dc_array_t, item: uintptr_t) { if !array.is_null() { (*array).add_uint(item); From c335348f20f6ea5e4fc69e2cfce7a18b280067fc Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 01:32:26 +0300 Subject: [PATCH 19/30] Implement dc_array_t::is_empty() --- src/dc_array.rs | 4 ++++ src/dc_chat.rs | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 259df106d..bf325812b 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -38,6 +38,10 @@ impl dc_array_t { pub fn add_id(&mut self, item: uint32_t) { self.add_uint(item as uintptr_t); } + + pub fn is_empty(&self) -> bool { + self.array.is_empty() + } } /** diff --git a/src/dc_chat.rs b/src/dc_chat.rs index 2668b08a3..45a78c35a 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -2164,7 +2164,7 @@ 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).array.is_empty() { + if !(*contacts).is_empty() { contact = dc_get_contact((*chat).context, (*contacts).array[0] as uint32_t); image_abs = dc_contact_get_profile_image(contact) } @@ -2185,7 +2185,7 @@ 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).array.is_empty() { + if !(*contacts).is_empty() { contact = dc_get_contact((*chat).context, (*contacts).array[0] as uint32_t); color = dc_str_to_color((*contact).addr) as uint32_t } From ea84edf13a5e8ec8b52bfb26588cd3e942c9984c Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 01:38:45 +0300 Subject: [PATCH 20/30] Implement dc_array_t::len() --- src/dc_array.rs | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index bf325812b..475e9d4a5 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -42,6 +42,11 @@ impl dc_array_t { pub fn is_empty(&self) -> bool { self.array.is_empty() } + + /// Returns the number of elements in the array. + pub fn len(&self) -> usize { + self.array.len() + } } /** @@ -84,18 +89,18 @@ pub unsafe fn dc_array_get_cnt(array: *const dc_array_t) -> size_t { if array.is_null() { return 0i32 as size_t; } - (*array).array.len() + (*array).len() } pub unsafe fn dc_array_get_uint(array: *const dc_array_t, index: size_t) -> uintptr_t { - if array.is_null() || index >= (*array).array.len() { + if array.is_null() || index >= (*array).len() { return 0i32 as uintptr_t; } (*array).array[index] } pub unsafe fn dc_array_get_id(array: *const dc_array_t, index: size_t) -> uint32_t { - if array.is_null() || index >= (*array).array.len() { + if array.is_null() || index >= (*array).len() { return 0i32 as uint32_t; } if (*array).type_0 == DC_ARRAY_LOCATIONS { @@ -105,7 +110,7 @@ pub unsafe fn dc_array_get_id(array: *const dc_array_t, index: size_t) -> uint32 } pub unsafe fn dc_array_get_ptr(array: *const dc_array_t, index: size_t) -> *mut libc::c_void { - if array.is_null() || index >= (*array).array.len() { + if array.is_null() || index >= (*array).len() { return 0 as *mut libc::c_void; } (*array).array[index] as *mut libc::c_void @@ -113,7 +118,7 @@ pub unsafe fn dc_array_get_ptr(array: *const dc_array_t, index: size_t) -> *mut pub unsafe fn dc_array_get_latitude(array: *const dc_array_t, index: size_t) -> libc::c_double { if array.is_null() - || index >= (*array).array.len() + || index >= (*array).len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 { @@ -124,7 +129,7 @@ pub unsafe fn dc_array_get_latitude(array: *const dc_array_t, index: size_t) -> pub unsafe fn dc_array_get_longitude(array: *const dc_array_t, index: size_t) -> libc::c_double { if array.is_null() - || index >= (*array).array.len() + || index >= (*array).len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 { @@ -135,7 +140,7 @@ pub unsafe fn dc_array_get_longitude(array: *const dc_array_t, index: size_t) -> pub unsafe fn dc_array_get_accuracy(array: *const dc_array_t, index: size_t) -> libc::c_double { if array.is_null() - || index >= (*array).array.len() + || index >= (*array).len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 { @@ -146,7 +151,7 @@ pub unsafe fn dc_array_get_accuracy(array: *const dc_array_t, index: size_t) -> pub unsafe fn dc_array_get_timestamp(array: *const dc_array_t, index: size_t) -> i64 { if array.is_null() - || index >= (*array).array.len() + || index >= (*array).len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 { @@ -157,7 +162,7 @@ pub unsafe fn dc_array_get_timestamp(array: *const dc_array_t, index: size_t) -> pub unsafe fn dc_array_get_chat_id(array: *const dc_array_t, index: size_t) -> uint32_t { if array.is_null() - || index >= (*array).array.len() + || index >= (*array).len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 { @@ -168,7 +173,7 @@ pub unsafe fn dc_array_get_chat_id(array: *const dc_array_t, index: size_t) -> u pub unsafe fn dc_array_get_contact_id(array: *const dc_array_t, index: size_t) -> uint32_t { if array.is_null() - || index >= (*array).array.len() + || index >= (*array).len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 { @@ -179,7 +184,7 @@ pub unsafe fn dc_array_get_contact_id(array: *const dc_array_t, index: size_t) - pub unsafe fn dc_array_get_msg_id(array: *const dc_array_t, index: size_t) -> uint32_t { if array.is_null() - || index >= (*array).array.len() + || index >= (*array).len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 { @@ -190,7 +195,7 @@ pub unsafe fn dc_array_get_msg_id(array: *const dc_array_t, index: size_t) -> ui pub unsafe fn dc_array_get_marker(array: *const dc_array_t, index: size_t) -> *mut libc::c_char { if array.is_null() - || index >= (*array).array.len() + || index >= (*array).len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 { @@ -215,7 +220,7 @@ 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 { if array.is_null() - || index >= (*array).array.len() + || index >= (*array).len() || (*array).type_0 != DC_ARRAY_LOCATIONS || (*array).array[index] == 0 { @@ -275,7 +280,7 @@ pub unsafe fn dc_array_duplicate(array: *const dc_array_t) -> *mut dc_array_t { } pub unsafe fn dc_array_sort_ids(array: *mut dc_array_t) { - if array.is_null() || (*array).array.len() <= 1 { + if array.is_null() || (*array).len() <= 1 { return; } (*array).array.sort(); @@ -288,7 +293,7 @@ pub unsafe fn dc_array_get_string( if array.is_null() || sep.is_null() { return dc_strdup(b"\x00" as *const u8 as *const libc::c_char); } - let cnt = (*array).array.len(); + let cnt = (*array).len(); let sep = as_str(sep); let res = From ea3c89e913eb387a225dcadf0e0d5633488ffb13 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 01:47:58 +0300 Subject: [PATCH 21/30] Move dc_array_unref logic inside dc_array_t implementation This will allow to make dc_array_t members private in the future. --- src/dc_array.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 475e9d4a5..495a65b99 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -47,6 +47,14 @@ impl dc_array_t { pub fn len(&self) -> usize { self.array.len() } + + pub unsafe fn unref(&mut self) { + if self.type_0 == DC_ARRAY_LOCATIONS { + for &e in self.array.iter() { + Box::from_raw(e as *mut dc_location); + } + } + } } /** @@ -61,11 +69,6 @@ pub unsafe fn dc_array_unref(array: *mut dc_array_t) { if array.is_null() { return; } - if (*array).type_0 == DC_ARRAY_LOCATIONS { - for &e in (*array).array.iter() { - Box::from_raw(e as *mut dc_location); - } - } Box::from_raw(array); } From c17632188aa35d1c220b165c7d42dad6e6d970a9 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 01:50:25 +0300 Subject: [PATCH 22/30] Avoid using return in dc_array_get_cnt implementation --- src/dc_array.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 495a65b99..6e8b2614b 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -90,9 +90,10 @@ 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() { - return 0i32 as size_t; + 0 + } else { + (*array).len() } - (*array).len() } pub unsafe fn dc_array_get_uint(array: *const dc_array_t, index: size_t) -> uintptr_t { From 928361429e007bf40a2d50404c474f6f162b7a84 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 01:57:44 +0300 Subject: [PATCH 23/30] Move dc_array_get_{uint,id} inside dc_array_t implementation --- src/dc_array.rs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 6e8b2614b..d97598aba 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -39,6 +39,18 @@ impl dc_array_t { self.add_uint(item as uintptr_t); } + pub fn get_uint(&self, index: usize) -> uintptr_t { + self.array[index] + } + + pub unsafe fn get_id(&self, index: usize) -> uint32_t { + if self.type_0 == DC_ARRAY_LOCATIONS { + (*(self.array[index] as *mut dc_location)).location_id + } else { + self.array[index] as uint32_t + } + } + pub fn is_empty(&self) -> bool { self.array.is_empty() } @@ -98,19 +110,18 @@ pub unsafe fn dc_array_get_cnt(array: *const dc_array_t) -> size_t { pub unsafe fn dc_array_get_uint(array: *const dc_array_t, index: size_t) -> uintptr_t { if array.is_null() || index >= (*array).len() { - return 0i32 as uintptr_t; + 0 + } else { + (*array).get_uint(index) } - (*array).array[index] } pub unsafe fn dc_array_get_id(array: *const dc_array_t, index: size_t) -> uint32_t { if array.is_null() || index >= (*array).len() { - return 0i32 as uint32_t; + 0 + } else { + (*array).get_id(index) } - if (*array).type_0 == DC_ARRAY_LOCATIONS { - return (*((*array).array[index] as *mut dc_location)).location_id; - } - (*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 { From 8b4acbb63a8dee66e7ff5a8ce43351ea0429967c Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 02:33:49 +0300 Subject: [PATCH 24/30] Move dc_array_get_ptr inside dc_array_t implementation --- src/dc_array.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index d97598aba..7f407a709 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -51,6 +51,10 @@ impl dc_array_t { } } + pub fn get_ptr(&self, index: size_t) -> *mut libc::c_void { + self.array[index] as *mut libc::c_void + } + pub fn is_empty(&self) -> bool { self.array.is_empty() } @@ -126,9 +130,10 @@ pub unsafe fn dc_array_get_id(array: *const dc_array_t, index: size_t) -> uint32 pub unsafe fn dc_array_get_ptr(array: *const dc_array_t, index: size_t) -> *mut libc::c_void { 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[index] as *mut libc::c_void } pub unsafe fn dc_array_get_latitude(array: *const dc_array_t, index: size_t) -> libc::c_double { From 51319f89e89c6fc6f8acc0a64b65d78f703b7509 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 23 Jul 2019 21:20:55 +0300 Subject: [PATCH 25/30] Create dc_array_t in dc_get_locations without unsafe --- src/dc_location.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/dc_location.rs b/src/dc_location.rs index b529ad123..90c4d84f0 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 = dc_array_new_locations(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_ptr(Box::into_raw(Box::new(location?)) as *mut libc::c_void); } - Ok(ret) + Ok(ret.as_ptr()) }, ) .unwrap_or_else(|_| std::ptr::null_mut()) From f27dda86ff0390585cd8bc93d332ff6f2aa08b3a Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Wed, 24 Jul 2019 02:02:55 +0300 Subject: [PATCH 26/30] Move dc_array_search_id into dc_array_t implementation --- src/dc_array.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 7f407a709..b438ed679 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -71,6 +71,15 @@ impl dc_array_t { } } } + + pub fn search_id(&self, needle: uintptr_t) -> Option { + for (i, &u) in self.array.iter().enumerate() { + if u == needle { + return Some(i); + } + } + None + } } /** @@ -258,15 +267,14 @@ pub unsafe fn dc_array_search_id( if array.is_null() { return false; } - for (i, &u) in (*array).array.iter().enumerate() { - if u == 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 } + true + } else { + false } - false } pub unsafe fn dc_array_get_raw(array: *const dc_array_t) -> *const uintptr_t { From 1cd7cb541cdb6fdff308da9b1c0131b276941994 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Wed, 24 Jul 2019 02:33:10 +0300 Subject: [PATCH 27/30] Rewrite most location array member accessors --- src/dc_array.rs | 113 +++++++++++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 49 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index b438ed679..7ad4f979b 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -55,6 +55,42 @@ impl dc_array_t { self.array[index] as *mut libc::c_void } + pub unsafe fn get_location_ptr(&self, index: usize) -> Option<*mut dc_location> { + if self.type_0 == DC_ARRAY_LOCATIONS && self.array[index] != 0 { + Some(self.array[index] as *mut dc_location) + } else { + None + } + } + + pub unsafe fn get_latitude(&self, index: usize) -> libc::c_double { + self.get_location_ptr(index).map_or(0.0, |v| (*v).latitude) + } + + pub unsafe fn get_longitude(&self, index: size_t) -> libc::c_double { + self.get_location_ptr(index).map_or(0.0, |v| (*v).longitude) + } + + pub unsafe fn get_accuracy(&self, index: size_t) -> libc::c_double { + self.get_location_ptr(index).map_or(0.0, |v| (*v).accuracy) + } + + pub unsafe fn get_timestamp(&self, index: size_t) -> i64 { + self.get_location_ptr(index).map_or(0, |v| (*v).timestamp) + } + + pub unsafe fn get_chat_id(&self, index: size_t) -> uint32_t { + self.get_location_ptr(index).map_or(0, |v| (*v).chat_id) + } + + pub unsafe fn get_contact_id(&self, index: size_t) -> uint32_t { + self.get_location_ptr(index).map_or(0, |v| (*v).contact_id) + } + + pub unsafe fn get_msg_id(&self, index: size_t) -> uint32_t { + self.get_location_ptr(index).map_or(0, |v| (*v).msg_id) + } + pub fn is_empty(&self) -> bool { self.array.is_empty() } @@ -146,80 +182,59 @@ pub unsafe fn dc_array_get_ptr(array: *const dc_array_t, index: size_t) -> *mut } pub unsafe fn dc_array_get_latitude(array: *const dc_array_t, index: size_t) -> libc::c_double { - if array.is_null() - || index >= (*array).len() - || (*array).type_0 != DC_ARRAY_LOCATIONS - || (*array).array[index] == 0 - { - return 0i32 as libc::c_double; + if array.is_null() || index >= (*array).len() { + 0.0 + } else { + (*array).get_latitude(index) } - (*((*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 { - if array.is_null() - || index >= (*array).len() - || (*array).type_0 != DC_ARRAY_LOCATIONS - || (*array).array[index] == 0 - { - return 0i32 as libc::c_double; + if array.is_null() || index >= (*array).len() { + 0.0 + } else { + (*array).get_longitude(index) } - (*((*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 { - if array.is_null() - || index >= (*array).len() - || (*array).type_0 != DC_ARRAY_LOCATIONS - || (*array).array[index] == 0 - { - return 0i32 as libc::c_double; + if array.is_null() || index >= (*array).len() { + 0.0 + } else { + (*array).get_accuracy(index) } - (*((*array).array[index] 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() - || index >= (*array).len() - || (*array).type_0 != DC_ARRAY_LOCATIONS - || (*array).array[index] == 0 - { - return 0; + if array.is_null() || index >= (*array).len() { + 0 + } else { + (*array).get_timestamp(index) } - (*((*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 { - if array.is_null() - || index >= (*array).len() - || (*array).type_0 != DC_ARRAY_LOCATIONS - || (*array).array[index] == 0 - { - return 0i32 as uint32_t; + if array.is_null() || index >= (*array).len() { + 0 + } else { + (*array).get_chat_id(index) } - (*((*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 { - if array.is_null() - || index >= (*array).len() - || (*array).type_0 != DC_ARRAY_LOCATIONS - || (*array).array[index] == 0 - { - return 0i32 as uint32_t; + if array.is_null() || index >= (*array).len() { + 0 + } else { + (*array).get_contact_id(index) } - (*((*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 { - if array.is_null() - || index >= (*array).len() - || (*array).type_0 != DC_ARRAY_LOCATIONS - || (*array).array[index] == 0 - { - return 0i32 as uint32_t; + if array.is_null() || index >= (*array).len() { + 0 + } else { + (*array).get_msg_id(index) } - (*((*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 { From 86d047f618f521b71bf0d138c9696b6750d6e687 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Sat, 27 Jul 2019 16:29:24 +0300 Subject: [PATCH 28/30] dc_chat: use get_id instead of accessing array fields directly --- src/dc_chat.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dc_chat.rs b/src/dc_chat.rs index 45a78c35a..301450c0b 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -2165,7 +2165,7 @@ pub unsafe fn dc_chat_get_profile_image(chat: *const Chat) -> *mut libc::c_char } else if (*chat).type_0 == 100i32 { contacts = dc_get_chat_contacts((*chat).context, (*chat).id); if !(*contacts).is_empty() { - contact = dc_get_contact((*chat).context, (*contacts).array[0] as uint32_t); + contact = dc_get_contact((*chat).context, (*contacts).get_id(0)); image_abs = dc_contact_get_profile_image(contact) } } @@ -2186,7 +2186,7 @@ pub unsafe fn dc_chat_get_color(chat: *const Chat) -> uint32_t { if (*chat).type_0 == 100i32 { contacts = dc_get_chat_contacts((*chat).context, (*chat).id); if !(*contacts).is_empty() { - contact = dc_get_contact((*chat).context, (*contacts).array[0] as uint32_t); + contact = dc_get_contact((*chat).context, (*contacts).get_id(0)); color = dc_str_to_color((*contact).addr) as uint32_t } } else { From ae1cbc959604b248f01c90f6a37d82224b99a040 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Sat, 27 Jul 2019 16:33:22 +0300 Subject: [PATCH 29/30] dc_array: store locations as Vec --- src/dc_array.rs | 181 ++++++++++++++++++++++++++------------------- src/dc_location.rs | 7 +- 2 files changed, 108 insertions(+), 80 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 7ad4f979b..8fb7b3e5e 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -2,29 +2,21 @@ use crate::dc_location::dc_location; use crate::dc_tools::*; use crate::types::*; -const DC_ARRAY_LOCATIONS: libc::c_int = 1; - /* * the structure behind dc_array_t */ #[derive(Clone)] -pub struct dc_array_t { - pub type_0: libc::c_int, - pub array: Vec, +pub enum dc_array_t { + Locations(Vec), + Uint(Vec), } impl dc_array_t { pub fn new(capacity: usize) -> Self { - dc_array_t { - type_0: 0, - array: Vec::with_capacity(capacity), - } + dc_array_t::Uint(Vec::with_capacity(capacity)) } /// Constructs a new, empty `dc_array_t` holding locations with specified `capacity`. pub fn new_locations(capacity: usize) -> Self { - dc_array_t { - type_0: DC_ARRAY_LOCATIONS, - array: Vec::with_capacity(capacity), - } + dc_array_t::Locations(Vec::with_capacity(capacity)) } pub fn as_ptr(self) -> *mut Self { @@ -32,89 +24,117 @@ impl dc_array_t { } pub fn add_uint(&mut self, item: uintptr_t) { - self.array.push(item); + 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 get_uint(&self, index: usize) -> uintptr_t { - self.array[index] + 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 unsafe fn get_id(&self, index: usize) -> uint32_t { - if self.type_0 == DC_ARRAY_LOCATIONS { - (*(self.array[index] as *mut dc_location)).location_id + pub fn get_uint(&self, index: usize) -> uintptr_t { + if let Self::Uint(array) = self { + array[index] } else { - self.array[index] as uint32_t + 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 { - self.array[index] as *mut libc::c_void - } - - pub unsafe fn get_location_ptr(&self, index: usize) -> Option<*mut dc_location> { - if self.type_0 == DC_ARRAY_LOCATIONS && self.array[index] != 0 { - Some(self.array[index] as *mut dc_location) + if let Self::Uint(array) = self { + array[index] as *mut libc::c_void } else { - None + panic!("Not an array of pointers"); } } - pub unsafe fn get_latitude(&self, index: usize) -> libc::c_double { - self.get_location_ptr(index).map_or(0.0, |v| (*v).latitude) + 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 unsafe fn get_longitude(&self, index: size_t) -> libc::c_double { - self.get_location_ptr(index).map_or(0.0, |v| (*v).longitude) + pub fn get_latitude(&self, index: usize) -> libc::c_double { + self.get_location(index).latitude } - pub unsafe fn get_accuracy(&self, index: size_t) -> libc::c_double { - self.get_location_ptr(index).map_or(0.0, |v| (*v).accuracy) + pub fn get_longitude(&self, index: size_t) -> libc::c_double { + self.get_location(index).longitude } - pub unsafe fn get_timestamp(&self, index: size_t) -> i64 { - self.get_location_ptr(index).map_or(0, |v| (*v).timestamp) + pub fn get_accuracy(&self, index: size_t) -> libc::c_double { + self.get_location(index).accuracy } - pub unsafe fn get_chat_id(&self, index: size_t) -> uint32_t { - self.get_location_ptr(index).map_or(0, |v| (*v).chat_id) + pub fn get_timestamp(&self, index: size_t) -> i64 { + self.get_location(index).timestamp } - pub unsafe fn get_contact_id(&self, index: size_t) -> uint32_t { - self.get_location_ptr(index).map_or(0, |v| (*v).contact_id) + pub fn get_chat_id(&self, index: size_t) -> uint32_t { + self.get_location(index).chat_id } - pub unsafe fn get_msg_id(&self, index: size_t) -> uint32_t { - self.get_location_ptr(index).map_or(0, |v| (*v).msg_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 { - self.array.is_empty() + 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 { - self.array.len() + match self { + Self::Locations(array) => array.len(), + Self::Uint(array) => array.len(), + } } - pub unsafe fn unref(&mut self) { - if self.type_0 == DC_ARRAY_LOCATIONS { - for &e in self.array.iter() { - Box::from_raw(e as *mut dc_location); - } + 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 { - for (i, &u) in self.array.iter().enumerate() { - if u == needle { - return Some(i); + 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"); } - None } } @@ -238,15 +258,16 @@ pub unsafe fn dc_array_get_msg_id(array: *const dc_array_t, index: size_t) -> ui } pub unsafe fn dc_array_get_marker(array: *const dc_array_t, index: size_t) -> *mut libc::c_char { - if array.is_null() - || index >= (*array).len() - || (*array).type_0 != DC_ARRAY_LOCATIONS - || (*array).array[index] == 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[index] 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() } @@ -263,15 +284,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() - || index >= (*array).len() - || (*array).type_0 != DC_ARRAY_LOCATIONS - || (*array).array[index] == 0 - { + if array.is_null() || index >= (*array).len() { return 0; } - (*((*array).array[index] 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( @@ -296,7 +317,11 @@ pub unsafe fn dc_array_get_raw(array: *const dc_array_t) -> *const uintptr_t { if array.is_null() { return 0 as *const uintptr_t; } - (*array).array.as_ptr() + if let dc_array_t::Uint(v) = &*array { + v.as_ptr() + } else { + panic!("Attempt to convert array of something other than uints to raw"); + } } pub fn dc_array_new(initsize: size_t) -> *mut dc_array_t { @@ -311,7 +336,7 @@ pub unsafe fn dc_array_empty(array: *mut dc_array_t) { if array.is_null() { return; } - (*array).array.clear(); + (*array).clear() } pub unsafe fn dc_array_duplicate(array: *const dc_array_t) -> *mut dc_array_t { @@ -326,7 +351,11 @@ pub unsafe fn dc_array_sort_ids(array: *mut dc_array_t) { if array.is_null() || (*array).len() <= 1 { return; } - (*array).array.sort(); + if let dc_array_t::Uint(v) = &mut *array { + v.sort(); + } else { + panic!("Attempt to sort array of something other than uints"); + } } pub unsafe fn dc_array_get_string( @@ -336,12 +365,11 @@ pub unsafe fn dc_array_get_string( if array.is_null() || sep.is_null() { return dc_strdup(b"\x00" as *const u8 as *const libc::c_char); } - let cnt = (*array).len(); - let sep = as_str(sep); + if let dc_array_t::Uint(v) = &*array { + let cnt = v.len(); + let sep = as_str(sep); - let res = - (*array) - .array + let res = v .iter() .enumerate() .fold(String::with_capacity(2 * cnt), |res, (i, n)| { @@ -351,7 +379,10 @@ pub unsafe fn dc_array_get_string( res + sep + &n.to_string() } }); - to_cstring(res) + to_cstring(res) + } else { + panic!("Attempt to get string from array of other type"); + } } #[cfg(test)] diff --git a/src/dc_location.rs b/src/dc_location.rs index 90c4d84f0..7401fda9f 100644 --- a/src/dc_location.rs +++ b/src/dc_location.rs @@ -250,7 +250,7 @@ pub fn dc_get_locations( let mut ret = dc_array_t::new_locations(500); for location in locations { - ret.add_ptr(Box::into_raw(Box::new(location?)) as *mut libc::c_void); + ret.add_location(location?); } Ok(ret.as_ptr()) }, @@ -582,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 }; From 21d94b1d0933dda43b77772a2af1c7143c86cab7 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Sat, 27 Jul 2019 16:52:57 +0300 Subject: [PATCH 30/30] Remove misplaced comment --- src/dc_array.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/dc_array.rs b/src/dc_array.rs index 8fb7b3e5e..15732a515 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -138,14 +138,6 @@ impl dc_array_t { } } -/** - * @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(array: *mut dc_array_t) { if array.is_null() { return;