summaryrefslogtreecommitdiff
path: root/rust/src/downloadprovider.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src/downloadprovider.rs')
-rw-r--r--rust/src/downloadprovider.rs302
1 files changed, 0 insertions, 302 deletions
diff --git a/rust/src/downloadprovider.rs b/rust/src/downloadprovider.rs
deleted file mode 100644
index 0d388486..00000000
--- a/rust/src/downloadprovider.rs
+++ /dev/null
@@ -1,302 +0,0 @@
-use crate::rc::{Array, CoreArrayProvider, Guard, CoreArrayProviderInner, Ref, RefCountable};
-use crate::settings::Settings;
-use crate::string::{BnStrCompatible, BnString};
-use binaryninjacore_sys::*;
-use std::collections::HashMap;
-use std::ffi::{c_void, CStr};
-use std::os::raw::c_char;
-use std::ptr::null_mut;
-use std::slice;
-
-pub struct DownloadProvider {
- handle: *mut BNDownloadProvider,
-}
-
-impl DownloadProvider {
- pub fn get<S: BnStrCompatible>(name: S) -> Option<DownloadProvider> {
- let result = unsafe {
- BNGetDownloadProviderByName(
- name.into_bytes_with_nul().as_ref().as_ptr() as *const c_char
- )
- };
- if result.is_null() {
- return None;
- }
- Some(DownloadProvider { handle: result })
- }
-
- pub fn list() -> Result<Array<DownloadProvider>, ()> {
- let mut count = 0;
- let list: *mut *mut BNDownloadProvider = unsafe { BNGetDownloadProviderList(&mut count) };
-
- if list.is_null() {
- return Err(());
- }
-
- Ok(unsafe { Array::new(list, count, ()) })
- }
-
- /// TODO : We may want to `impl Default`....excessive error checking might be preventing us from doing so
- pub fn try_default() -> Result<DownloadProvider, ()> {
- let s = Settings::new("");
- let dp_name = s.get_string("network.downloadProviderName", None, None);
- Self::get(dp_name).ok_or(())
- }
-
- pub(crate) fn from_raw(handle: *mut BNDownloadProvider) -> DownloadProvider {
- Self { handle }
- }
-
- pub fn create_instance(&self) -> Result<Ref<DownloadInstance>, ()> {
- let result: *mut BNDownloadInstance =
- unsafe { BNCreateDownloadProviderInstance(self.handle) };
- if result.is_null() {
- return Err(());
- }
-
- Ok(unsafe { DownloadInstance::ref_from_raw(result) })
- }
-}
-
-impl CoreArrayProvider for DownloadProvider {
- type Raw = *mut BNDownloadProvider;
- type Context = ();
- type Wrapped<'a> = Guard<'a, DownloadProvider>;
-}
-
-unsafe impl CoreArrayProviderInner for DownloadProvider {
- unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
- BNFreeDownloadProviderList(raw);
- }
- unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
- Guard::new(DownloadProvider::from_raw(*raw), &())
- }
-}
-
-pub struct DownloadInstanceOutputCallbacks {
- pub write: Option<Box<dyn FnMut(&[u8]) -> usize>>,
- pub progress: Option<Box<dyn FnMut(u64, u64) -> bool>>,
-}
-
-pub struct DownloadInstanceInputOutputCallbacks {
- pub read: Option<Box<dyn FnMut(&mut [u8]) -> Option<isize>>>,
- pub write: Option<Box<dyn FnMut(&[u8]) -> usize>>,
- pub progress: Option<Box<dyn FnMut(u64, u64) -> bool>>,
-}
-
-pub struct DownloadResponse {
- pub status_code: u16,
- pub headers: HashMap<String, String>,
-}
-
-pub struct DownloadInstance {
- handle: *mut BNDownloadInstance,
-}
-
-impl DownloadInstance {
- pub(crate) unsafe fn from_raw(handle: *mut BNDownloadInstance) -> Self {
- debug_assert!(!handle.is_null());
-
- Self { handle }
- }
-
- pub(crate) unsafe fn ref_from_raw(handle: *mut BNDownloadInstance) -> Ref<Self> {
- Ref::new(Self::from_raw(handle))
- }
-
- fn get_error(&self) -> BnString {
- let err: *mut c_char = unsafe { BNGetErrorForDownloadInstance(self.handle) };
- unsafe { BnString::from_raw(err) }
- }
-
- unsafe extern "C" fn o_write_callback(data: *mut u8, len: u64, ctxt: *mut c_void) -> u64 {
- let callbacks = ctxt as *mut DownloadInstanceOutputCallbacks;
- if let Some(func) = &mut (*callbacks).write {
- let slice = slice::from_raw_parts(data, len as usize);
- let result = (func)(slice);
- result as u64
- } else {
- 0u64
- }
- }
-
- unsafe extern "C" fn o_progress_callback(ctxt: *mut c_void, progress: u64, total: u64) -> bool {
- let callbacks = ctxt as *mut DownloadInstanceOutputCallbacks;
- if let Some(func) = &mut (*callbacks).progress {
- (func)(progress, total)
- } else {
- true
- }
- }
-
- pub fn perform_request<S: BnStrCompatible>(
- &mut self,
- url: S,
- callbacks: DownloadInstanceOutputCallbacks,
- ) -> Result<(), BnString> {
- let callbacks = Box::into_raw(Box::new(callbacks));
- let mut cbs = BNDownloadInstanceOutputCallbacks {
- writeCallback: Some(Self::o_write_callback),
- writeContext: callbacks as *mut c_void,
- progressCallback: Some(Self::o_progress_callback),
- progressContext: callbacks as *mut c_void,
- };
-
- let result = unsafe {
- BNPerformDownloadRequest(
- self.handle,
- url.into_bytes_with_nul().as_ref().as_ptr() as *const c_char,
- &mut cbs as *mut BNDownloadInstanceOutputCallbacks,
- )
- };
-
- // Drop it
- unsafe { drop(Box::from_raw(callbacks)) };
- if result < 0 {
- Err(self.get_error())
- } else {
- Ok(())
- }
- }
-
- unsafe extern "C" fn i_read_callback(data: *mut u8, len: u64, ctxt: *mut c_void) -> i64 {
- let callbacks = ctxt as *mut DownloadInstanceInputOutputCallbacks;
- if let Some(func) = &mut (*callbacks).read {
- let slice = slice::from_raw_parts_mut(data, len as usize);
- let result = (func)(slice);
- if let Some(count) = result {
- count as i64
- } else {
- -1
- }
- } else {
- 0
- }
- }
-
- unsafe extern "C" fn i_write_callback(data: *mut u8, len: u64, ctxt: *mut c_void) -> u64 {
- let callbacks = ctxt as *mut DownloadInstanceInputOutputCallbacks;
- if let Some(func) = &mut (*callbacks).write {
- let slice = slice::from_raw_parts(data, len as usize);
- let result = (func)(slice);
- result as u64
- } else {
- 0
- }
- }
-
- unsafe extern "C" fn i_progress_callback(ctxt: *mut c_void, progress: u64, total: u64) -> bool {
- let callbacks = ctxt as *mut DownloadInstanceInputOutputCallbacks;
- if let Some(func) = &mut (*callbacks).progress {
- (func)(progress, total)
- } else {
- true
- }
- }
-
- pub fn perform_custom_request<
- M: BnStrCompatible,
- U: BnStrCompatible,
- HK: BnStrCompatible,
- HV: BnStrCompatible,
- I: IntoIterator<Item = (HK, HV)>,
- >(
- &mut self,
- method: M,
- url: U,
- headers: I,
- callbacks: DownloadInstanceInputOutputCallbacks,
- ) -> Result<DownloadResponse, BnString> {
- let mut header_keys = vec![];
- let mut header_values = vec![];
- for (key, value) in headers {
- header_keys.push(key.into_bytes_with_nul());
- header_values.push(value.into_bytes_with_nul());
- }
-
- let mut header_key_ptrs = vec![];
- let mut header_value_ptrs = vec![];
-
- for (key, value) in header_keys.iter().zip(header_values.iter()) {
- header_key_ptrs.push(key.as_ref().as_ptr() as *const c_char);
- header_value_ptrs.push(value.as_ref().as_ptr() as *const c_char);
- }
-
- let callbacks = Box::into_raw(Box::new(callbacks));
- let mut cbs = BNDownloadInstanceInputOutputCallbacks {
- readCallback: Some(Self::i_read_callback),
- readContext: callbacks as *mut c_void,
- writeCallback: Some(Self::i_write_callback),
- writeContext: callbacks as *mut c_void,
- progressCallback: Some(Self::i_progress_callback),
- progressContext: callbacks as *mut c_void,
- };
-
- let mut response: *mut BNDownloadInstanceResponse = null_mut();
-
- let result = unsafe {
- BNPerformCustomRequest(
- self.handle,
- method.into_bytes_with_nul().as_ref().as_ptr() as *const c_char,
- url.into_bytes_with_nul().as_ref().as_ptr() as *const c_char,
- header_key_ptrs.len() as u64,
- header_key_ptrs.as_ptr(),
- header_value_ptrs.as_ptr(),
- &mut response as *mut *mut BNDownloadInstanceResponse,
- &mut cbs as *mut BNDownloadInstanceInputOutputCallbacks,
- )
- };
-
- if result < 0 {
- unsafe { BNFreeDownloadInstanceResponse(response) };
- return Err(self.get_error());
- }
-
- let mut response_headers = HashMap::new();
- unsafe {
- let response_header_keys: &[*mut c_char] =
- slice::from_raw_parts((*response).headerKeys, (*response).headerCount as usize);
- let response_header_values: &[*mut c_char] =
- slice::from_raw_parts((*response).headerValues, (*response).headerCount as usize);
-
- for (key, value) in response_header_keys
- .iter()
- .zip(response_header_values.iter())
- {
- response_headers.insert(
- CStr::from_ptr(*key).to_str().unwrap().to_owned(),
- CStr::from_ptr(*value).to_str().unwrap().to_owned(),
- );
- }
- }
-
- let r = DownloadResponse {
- status_code: unsafe { (*response).statusCode },
- headers: response_headers,
- };
-
- unsafe { BNFreeDownloadInstanceResponse(response) };
-
- Ok(r)
- }
-}
-
-impl ToOwned for DownloadInstance {
- type Owned = Ref<Self>;
-
- fn to_owned(&self) -> Self::Owned {
- unsafe { RefCountable::inc_ref(self) }
- }
-}
-
-unsafe impl RefCountable for DownloadInstance {
- unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
- Ref::new(Self {
- handle: BNNewDownloadInstanceReference(handle.handle),
- })
- }
-
- unsafe fn dec_ref(handle: &Self) {
- BNFreeDownloadInstance(handle.handle);
- }
-}