Skip to content

Commit

Permalink
Merge pull request #562 from sdroege/0.15-backports
Browse files Browse the repository at this point in the history
0.15 backports
  • Loading branch information
sdroege authored Feb 18, 2022
2 parents 6d670d0 + a617abb commit 2bd4310
Show file tree
Hide file tree
Showing 50 changed files with 494 additions and 59 deletions.
22 changes: 17 additions & 5 deletions cairo/src/image_surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,12 @@ impl ImageSurface {
return Err(BorrowError::from(Error::SurfaceFinished));
}
let len = self.height() as usize * self.stride() as usize;
f(slice::from_raw_parts(ptr, len));
let data = if len == 0 {
&[]
} else {
slice::from_raw_parts(ptr, len)
};
f(data);
}
Ok(())
}
Expand Down Expand Up @@ -186,7 +191,9 @@ impl AsRef<[u8]> for ImageSurfaceDataOwned {
let len = (self.surface.stride() as usize) * (self.surface.height() as usize);
unsafe {
let ptr = ffi::cairo_image_surface_get_data(self.surface.to_raw_none());
debug_assert!(!ptr.is_null());
if ptr.is_null() || len == 0 {
return &[];
}
slice::from_raw_parts(ptr, len)
}
}
Expand All @@ -197,7 +204,9 @@ impl AsMut<[u8]> for ImageSurfaceDataOwned {
let len = (self.surface.stride() as usize) * (self.surface.height() as usize);
unsafe {
let ptr = ffi::cairo_image_surface_get_data(self.surface.to_raw_none());
debug_assert!(!ptr.is_null());
if ptr.is_null() || len == 0 {
return &mut [];
}
slice::from_raw_parts_mut(ptr, len)
}
}
Expand Down Expand Up @@ -231,11 +240,14 @@ impl<'a> ImageSurfaceData<'a> {
fn new(surface: &'a mut ImageSurface) -> ImageSurfaceData<'a> {
unsafe {
let ptr = ffi::cairo_image_surface_get_data(surface.to_raw_none());
debug_assert!(!ptr.is_null());
let len = (surface.stride() as usize) * (surface.height() as usize);
ImageSurfaceData {
surface,
slice: slice::from_raw_parts_mut(ptr, len),
slice: if ptr.is_null() || len == 0 {
&mut []
} else {
slice::from_raw_parts_mut(ptr, len)
},
dirty: false,
}
}
Expand Down
12 changes: 10 additions & 2 deletions cairo/src/image_surface_png.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ unsafe extern "C" fn read_func<R: Read>(
return Error::ReadError.into();
}

let buffer = slice::from_raw_parts_mut(data, len as usize);
let buffer = if data.is_null() || len == 0 {
&mut []
} else {
slice::from_raw_parts_mut(data, len as usize)
};
let result = std::panic::catch_unwind(AssertUnwindSafe(|| read_env.reader.read_exact(buffer)));
match result {
Ok(Ok(())) => ffi::STATUS_SUCCESS,
Expand Down Expand Up @@ -63,7 +67,11 @@ unsafe extern "C" fn write_func<W: Write>(
return Error::WriteError.into();
}

let buffer = slice::from_raw_parts(data, len as usize);
let buffer = if data.is_null() || len == 0 {
&[]
} else {
slice::from_raw_parts(data, len as usize)
};
let result = std::panic::catch_unwind(AssertUnwindSafe(|| write_env.writer.write_all(buffer)));
match result {
Ok(Ok(())) => ffi::STATUS_SUCCESS,
Expand Down
7 changes: 6 additions & 1 deletion cairo/src/pdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ impl PdfSurface {
let mut num_vers = mem::MaybeUninit::uninit();
ffi::cairo_pdf_get_versions(&mut vers_ptr, num_vers.as_mut_ptr());

std::slice::from_raw_parts(vers_ptr, num_vers.assume_init() as _)
let num_vers = num_vers.assume_init();
if num_vers == 0 {
&[]
} else {
std::slice::from_raw_parts(vers_ptr, num_vers as _)
}
};
vers_slice.iter().map(|v| PdfVersion::from(*v))
}
Expand Down
7 changes: 6 additions & 1 deletion cairo/src/ps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ impl PsSurface {
let mut num_vers = mem::MaybeUninit::uninit();
ffi::cairo_ps_get_levels(&mut vers_ptr, num_vers.as_mut_ptr());

std::slice::from_raw_parts(vers_ptr, num_vers.assume_init() as _)
let num_vers = num_vers.assume_init();
if num_vers == 0 {
&[]
} else {
std::slice::from_raw_parts(vers_ptr, num_vers as _)
}
};

lvls_slice.iter().map(|v| PsLevel::from(*v))
Expand Down
8 changes: 7 additions & 1 deletion cairo/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@ extern "C" fn write_callback<W: io::Write + 'static>(
// with a W parameter consistent with the box that was unsized to `Box<dyn Any>`.
let stream = unsafe { stream.downcast_mut_unchecked::<W>() };
// Safety: this is the callback contract from cairo’s API
let data = unsafe { std::slice::from_raw_parts(data, length as usize) };
let data = unsafe {
if data.is_null() || length == 0 {
&[]
} else {
std::slice::from_raw_parts(data, length as usize)
}
};
// Because `<W as Write>::write_all` is a generic,
// we must conservatively assume that it can panic.
let result = std::panic::catch_unwind(AssertUnwindSafe(|| stream.write_all(data)));
Expand Down
7 changes: 6 additions & 1 deletion cairo/src/svg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,12 @@ impl SvgSurface {
let mut num_vers = mem::MaybeUninit::uninit();
ffi::cairo_svg_get_versions(&mut vers_ptr, num_vers.as_mut_ptr());

std::slice::from_raw_parts(vers_ptr, num_vers.assume_init() as _)
let num_vers = num_vers.assume_init();
if num_vers == 0 {
&[]
} else {
std::slice::from_raw_parts(vers_ptr, num_vers as _)
}
};

vers_slice.iter().map(|v| SvgVersion::from(*v))
Expand Down
2 changes: 1 addition & 1 deletion gdk-pixbuf/src/auto/versions.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Generated by gir (https://github.com/gtk-rs/gir @ 78e3d3c22343)
from gir-files (https://github.com/gtk-rs/gir-files @ 86743c80d34b)
from gir-files (https://github.com/gtk-rs/gir-files @ 68003b4b40e5)
3 changes: 3 additions & 0 deletions gdk-pixbuf/src/pixbuf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,9 @@ impl Pixbuf {
pub unsafe fn pixels(&self) -> &mut [u8] {
let mut len = 0;
let ptr = ffi::gdk_pixbuf_get_pixels_with_length(self.to_glib_none().0, &mut len);
if len == 0 {
return &mut [];
}
slice::from_raw_parts_mut(ptr, len as usize)
}

Expand Down
2 changes: 1 addition & 1 deletion gdk-pixbuf/sys/versions.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Generated by gir (https://github.com/gtk-rs/gir @ 78e3d3c22343)
from gir-files (https://github.com/gtk-rs/gir-files @ 86743c80d34b)
from gir-files (https://github.com/gtk-rs/gir-files @ 68003b4b40e5)
5 changes: 5 additions & 0 deletions gio/Gir.toml
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,11 @@ manual_traits = ["FileExtManual"]
manual = true
doc_trait_name = "FileExtManual"
[[object.function]]
name = "move_async"
# Multiple callbacks
manual = true
doc_trait_name = "FileExtManual"
[[object.function]]
name = "load_partial_contents_async"
# Multiple callbacks
manual = true
Expand Down
2 changes: 1 addition & 1 deletion gio/src/auto/versions.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Generated by gir (https://github.com/gtk-rs/gir @ 78e3d3c22343)
from gir-files (https://github.com/gtk-rs/gir-files @ 86743c80d34b)
from gir-files (https://github.com/gtk-rs/gir-files @ 68003b4b40e5)
162 changes: 157 additions & 5 deletions gio/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,31 @@ pub trait FileExtManual: Sized {
Pin<Box<dyn std::future::Future<Output = Result<(u64, u64, u64), glib::Error>> + 'static>>,
Pin<Box<dyn futures_core::stream::Stream<Item = (bool, u64, u64, u64)> + 'static>>,
);

#[cfg(any(feature = "v2_72", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v2_72")))]
#[doc(alias = "g_file_move_async")]
fn move_async<Q: FnOnce(Result<(), glib::Error>) + 'static>(
&self,
destination: &impl IsA<File>,
flags: crate::FileCopyFlags,
io_priority: glib::Priority,
cancellable: Option<&impl IsA<Cancellable>>,
progress_callback: Option<Box<dyn FnMut(i64, i64)>>,
callback: Q,
);

#[cfg(any(feature = "v2_72", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v2_72")))]
fn move_future(
&self,
destination: &(impl IsA<File> + Clone + 'static),
flags: crate::FileCopyFlags,
io_priority: glib::Priority,
) -> (
Pin<Box<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>>,
Pin<Box<dyn futures_core::stream::Stream<Item = (i64, i64)> + 'static>>,
);
}

impl<O: IsA<File>> FileExtManual for O {
Expand Down Expand Up @@ -506,11 +531,13 @@ impl<O: IsA<File>> FileExtManual for O {
glib::thread_guard::ThreadGuard<Q>,
RefCell<glib::thread_guard::ThreadGuard<P>>,
) = &*(user_data as *const _);
(&mut *callback.1.borrow_mut().get_mut())(slice::from_raw_parts(
file_contents as *const u8,
file_size as usize,
))
.into_glib()
let data = if file_size == 0 {
&[]
} else {
slice::from_raw_parts(file_contents as *const u8, file_size as usize)
};

(&mut *callback.1.borrow_mut().get_mut())(data).into_glib()
}

let user_data = Box::into_raw(user_data) as *mut _;
Expand Down Expand Up @@ -736,4 +763,129 @@ impl<O: IsA<File>> FileExtManual for O {

(fut, Box::pin(receiver))
}

#[cfg(any(feature = "v2_72", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v2_72")))]
fn move_async<Q: FnOnce(Result<(), glib::Error>) + 'static>(
&self,
destination: &impl IsA<File>,
flags: crate::FileCopyFlags,
io_priority: glib::Priority,
cancellable: Option<&impl IsA<Cancellable>>,
progress_callback: Option<Box<dyn FnMut(i64, i64)>>,
callback: Q,
) {
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 progress_trampoline = if progress_callback.is_some() {
Some(move_async_progress_trampoline::<Q> as _)
} else {
None
};

let user_data: Box<(
glib::thread_guard::ThreadGuard<Q>,
RefCell<Option<glib::thread_guard::ThreadGuard<Box<dyn FnMut(i64, i64)>>>>,
)> = Box::new((
glib::thread_guard::ThreadGuard::new(callback),
RefCell::new(progress_callback.map(glib::thread_guard::ThreadGuard::new)),
));
unsafe extern "C" fn move_async_trampoline<Q: FnOnce(Result<(), glib::Error>) + 'static>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut crate::ffi::GAsyncResult,
user_data: glib::ffi::gpointer,
) {
let mut error = ptr::null_mut();
ffi::g_file_move_finish(_source_object as *mut _, res, &mut error);
let result = if error.is_null() {
Ok(())
} else {
Err(from_glib_full(error))
};
let callback: Box<(
glib::thread_guard::ThreadGuard<Q>,
RefCell<Option<glib::thread_guard::ThreadGuard<Box<dyn FnMut(i64, i64)>>>>,
)> = Box::from_raw(user_data as *mut _);
let callback = callback.0.into_inner();
callback(result);
}
unsafe extern "C" fn move_async_progress_trampoline<
Q: FnOnce(Result<(), glib::Error>) + 'static,
>(
current_num_bytes: i64,
total_num_bytes: i64,
user_data: glib::ffi::gpointer,
) {
let callback: &(
glib::thread_guard::ThreadGuard<Q>,
RefCell<Option<glib::thread_guard::ThreadGuard<Box<dyn FnMut(i64, i64)>>>>,
) = &*(user_data as *const _);
(callback
.1
.borrow_mut()
.as_mut()
.expect("no closure")
.get_mut())(current_num_bytes, total_num_bytes);
}

let user_data = Box::into_raw(user_data) as *mut _;

unsafe {
ffi::g_file_move_async(
self.as_ref().to_glib_none().0,
destination.as_ref().to_glib_none().0,
flags.into_glib(),
io_priority.into_glib(),
cancellable.map(|p| p.as_ref()).to_glib_none().0,
progress_trampoline,
user_data,
Some(move_async_trampoline::<Q>),
user_data,
);
}
}

#[cfg(any(feature = "v2_72", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v2_72")))]
fn move_future(
&self,
destination: &(impl IsA<File> + Clone + 'static),
flags: crate::FileCopyFlags,
io_priority: glib::Priority,
) -> (
Pin<Box<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>>,
Pin<Box<dyn futures_core::stream::Stream<Item = (i64, i64)> + 'static>>,
) {
let destination = destination.clone();

let (sender, receiver) = futures_channel::mpsc::unbounded();

let fut = Box::pin(crate::GioFuture::new(
self,
move |obj, cancellable, send| {
obj.move_async(
&destination,
flags,
io_priority,
Some(cancellable),
Some(Box::new(move |current_num_bytes, total_num_bytes| {
let _ = sender.unbounded_send((current_num_bytes, total_num_bytes));
})),
move |res| {
send.resolve(res);
},
);
},
));

(fut, Box::pin(receiver))
}
}
6 changes: 5 additions & 1 deletion gio/src/subclass/input_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,11 @@ unsafe extern "C" fn stream_read<T: InputStreamImpl>(

match imp.read(
wrap.unsafe_cast_ref(),
slice::from_raw_parts_mut(buffer as *mut u8, count),
if count == 0 {
&mut []
} else {
slice::from_raw_parts_mut(buffer as *mut u8, count)
},
Option::<Cancellable>::from_glib_borrow(cancellable)
.as_ref()
.as_ref(),
Expand Down
6 changes: 5 additions & 1 deletion gio/src/subclass/output_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,11 @@ unsafe extern "C" fn stream_write<T: OutputStreamImpl>(

match imp.write(
wrap.unsafe_cast_ref(),
slice::from_raw_parts(buffer as *const u8, count),
if count == 0 {
&[]
} else {
slice::from_raw_parts(buffer as *const u8, count)
},
Option::<Cancellable>::from_glib_borrow(cancellable)
.as_ref()
.as_ref(),
Expand Down
2 changes: 1 addition & 1 deletion gio/src/unix_socket_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl<O: IsA<UnixSocketAddress>> UnixSocketAddressExtManual for O {

let path = unsafe {
let path = ffi::g_unix_socket_address_get_path(self.as_ref().to_glib_none().0);
if path.is_null() {
if path.is_null() || self.path_len() == 0 {
&[]
} else {
slice::from_raw_parts(path as *const u8, self.path_len())
Expand Down
Loading

0 comments on commit 2bd4310

Please sign in to comment.