Skip to content

Commit

Permalink
Merge pull request #1238 from sdroege/data-input-stream-no-const
Browse files Browse the repository at this point in the history
gio: Don't wrongly cast DataInputStream byte arrays to a const pointer
  • Loading branch information
sdroege committed Dec 3, 2023
2 parents a0d5234 + 755e082 commit 6b1bdba
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 147 deletions.
10 changes: 10 additions & 0 deletions gio/Gir.toml
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,16 @@ manual_traits = ["FileExtManual"]
name = "new_tmp_dir_async"
manual = true
doc_trait_name = "FileExtManual"
[[object.function]]
name = "load_contents"
# Use `Slice<u8>`
manual = true
doc_trait_name = "FileExtManual"
[[object.function]]
name = "load_contents_async"
# Use `Slice<u8>`
manual = true
doc_trait_name = "FileExtManual"

[[object]]
name = "Gio.FileAttributeInfoList"
Expand Down
111 changes: 0 additions & 111 deletions gio/src/auto/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -903,117 +903,6 @@ pub trait FileExt: IsA<File> + sealed::Sealed + 'static {
))
}

#[doc(alias = "g_file_load_contents")]
fn load_contents(
&self,
cancellable: Option<&impl IsA<Cancellable>>,
) -> Result<(Vec<u8>, Option<glib::GString>), glib::Error> {
unsafe {
let mut contents = std::ptr::null_mut();
let mut length = std::mem::MaybeUninit::uninit();
let mut etag_out = std::ptr::null_mut();
let mut error = std::ptr::null_mut();
let is_ok = ffi::g_file_load_contents(
self.as_ref().to_glib_none().0,
cancellable.map(|p| p.as_ref()).to_glib_none().0,
&mut contents,
length.as_mut_ptr(),
&mut etag_out,
&mut error,
);
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok((
FromGlibContainer::from_glib_full_num(contents, length.assume_init() as _),
from_glib_full(etag_out),
))
} else {
Err(from_glib_full(error))
}
}
}

#[doc(alias = "g_file_load_contents_async")]
fn load_contents_async<
P: FnOnce(Result<(Vec<u8>, Option<glib::GString>), glib::Error>) + 'static,
>(
&self,
cancellable: Option<&impl IsA<Cancellable>>,
callback: P,
) {
let main_context = glib::MainContext::ref_thread_default();
let is_main_context_owner = main_context.is_owner();
let has_acquired_main_context = (!is_main_context_owner)
.then(|| main_context.acquire().ok())
.flatten();
assert!(
is_main_context_owner || has_acquired_main_context.is_some(),
"Async operations only allowed if the thread is owning the MainContext"
);

let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn load_contents_async_trampoline<
P: FnOnce(Result<(Vec<u8>, Option<glib::GString>), glib::Error>) + 'static,
>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut crate::ffi::GAsyncResult,
user_data: glib::ffi::gpointer,
) {
let mut error = std::ptr::null_mut();
let mut contents = std::ptr::null_mut();
let mut length = std::mem::MaybeUninit::uninit();
let mut etag_out = std::ptr::null_mut();
let _ = ffi::g_file_load_contents_finish(
_source_object as *mut _,
res,
&mut contents,
length.as_mut_ptr(),
&mut etag_out,
&mut error,
);
let result = if error.is_null() {
Ok((
FromGlibContainer::from_glib_full_num(contents, length.assume_init() as _),
from_glib_full(etag_out),
))
} else {
Err(from_glib_full(error))
};
let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::from_raw(user_data as *mut _);
let callback: P = callback.into_inner();
callback(result);
}
let callback = load_contents_async_trampoline::<P>;
unsafe {
ffi::g_file_load_contents_async(
self.as_ref().to_glib_none().0,
cancellable.map(|p| p.as_ref()).to_glib_none().0,
Some(callback),
Box_::into_raw(user_data) as *mut _,
);
}
}

fn load_contents_future(
&self,
) -> Pin<
Box_<
dyn std::future::Future<Output = Result<(Vec<u8>, Option<glib::GString>), glib::Error>>
+ 'static,
>,
> {
Box_::pin(crate::GioFuture::new(
self,
move |obj, cancellable, send| {
obj.load_contents_async(Some(cancellable), move |res| {
send.resolve(res);
});
},
))
}

#[doc(alias = "g_file_make_directory")]
fn make_directory(
&self,
Expand Down
36 changes: 26 additions & 10 deletions gio/src/data_input_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'sta
fn read_line<P: IsA<Cancellable>>(
&self,
cancellable: Option<&P>,
) -> Result<Vec<u8>, glib::Error> {
) -> Result<glib::collections::Slice<u8>, glib::Error> {
unsafe {
let mut length = mem::MaybeUninit::uninit();
let mut error = ptr::null_mut();
Expand All @@ -36,7 +36,10 @@ pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'sta
}

#[doc(alias = "g_data_input_stream_read_line_async")]
fn read_line_async<P: IsA<Cancellable>, Q: FnOnce(Result<Vec<u8>, glib::Error>) + 'static>(
fn read_line_async<
P: IsA<Cancellable>,
Q: FnOnce(Result<glib::collections::Slice<u8>, glib::Error>) + 'static,
>(
&self,
io_priority: glib::Priority,
cancellable: Option<&P>,
Expand All @@ -55,7 +58,7 @@ pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'sta
let user_data: Box_<glib::thread_guard::ThreadGuard<Q>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn read_line_async_trampoline<
Q: FnOnce(Result<Vec<u8>, glib::Error>) + 'static,
Q: FnOnce(Result<glib::collections::Slice<u8>, glib::Error>) + 'static,
>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut ffi::GAsyncResult,
Expand Down Expand Up @@ -95,7 +98,12 @@ pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'sta
fn read_line_future(
&self,
io_priority: glib::Priority,
) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<u8>, glib::Error>> + 'static>> {
) -> Pin<
Box_<
dyn std::future::Future<Output = Result<glib::collections::Slice<u8>, glib::Error>>
+ 'static,
>,
> {
Box_::pin(crate::GioFuture::new(
self,
move |obj, cancellable, send| {
Expand Down Expand Up @@ -204,7 +212,7 @@ pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'sta
&self,
stop_chars: &[u8],
cancellable: Option<&P>,
) -> Result<Vec<u8>, glib::Error> {
) -> Result<glib::collections::Slice<u8>, glib::Error> {
let stop_chars_len = stop_chars.len() as isize;
unsafe {
let mut error = ptr::null_mut();
Expand All @@ -220,7 +228,7 @@ pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'sta
if error.is_null() {
let length = length.assume_init();
Ok(FromGlibContainer::from_glib_full_num(
ret as *const _,
ret as *mut u8,
length,
))
} else {
Expand All @@ -230,7 +238,10 @@ pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'sta
}

#[doc(alias = "g_data_input_stream_read_upto_async")]
fn read_upto_async<P: IsA<Cancellable>, Q: FnOnce(Result<Vec<u8>, glib::Error>) + 'static>(
fn read_upto_async<
P: IsA<Cancellable>,
Q: FnOnce(Result<glib::collections::Slice<u8>, glib::Error>) + 'static,
>(
&self,
stop_chars: &[u8],
io_priority: glib::Priority,
Expand All @@ -251,7 +262,7 @@ pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'sta
let user_data: Box_<glib::thread_guard::ThreadGuard<Q>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn read_upto_async_trampoline<
Q: FnOnce(Result<Vec<u8>, glib::Error>) + 'static,
Q: FnOnce(Result<glib::collections::Slice<u8>, glib::Error>) + 'static,
>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut ffi::GAsyncResult,
Expand All @@ -268,7 +279,7 @@ pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'sta
let result = if error.is_null() {
let length = length.assume_init();
Ok(FromGlibContainer::from_glib_full_num(
ret as *const _,
ret as *mut u8,
length,
))
} else {
Expand Down Expand Up @@ -297,7 +308,12 @@ pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'sta
&self,
stop_chars: &[u8],
io_priority: glib::Priority,
) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<u8>, glib::Error>> + 'static>> {
) -> Pin<
Box_<
dyn std::future::Future<Output = Result<glib::collections::Slice<u8>, glib::Error>>
+ 'static,
>,
> {
let stop_chars = Vec::from(stop_chars);
Box_::pin(crate::GioFuture::new(
self,
Expand Down

0 comments on commit 6b1bdba

Please sign in to comment.