From 27e4f7fb310fe216ac9ffe4e1957f6b20c73fb01 Mon Sep 17 00:00:00 2001 From: Andrea Ciliberti Date: Sat, 18 Feb 2023 15:31:26 +0100 Subject: [PATCH] New error variant and fixed nits --- ctru-rs/examples/camera-image.rs | 5 +++-- ctru-rs/src/error.rs | 8 ++++++-- ctru-rs/src/services/cam.rs | 14 +++++--------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/ctru-rs/examples/camera-image.rs b/ctru-rs/examples/camera-image.rs index aa4dff9..b46b591 100644 --- a/ctru-rs/examples/camera-image.rs +++ b/ctru-rs/examples/camera-image.rs @@ -119,9 +119,10 @@ fn rotate_image_to_screen(src: &[u8], framebuf: *mut u8, width: usize, height: u let draw_index = (draw_x * height + draw_y) * 2; // This 2 stands for the number of bytes per pixel (16 bits) unsafe { + // We'll work with pointers since the frambuffer is a raw pointer regardless. + // The offsets are completely safe as long as the width and height are correct. let pixel_pointer = framebuf.offset(draw_index as isize); - *pixel_pointer = src[read_index]; - *pixel_pointer.offset(1) = src[read_index + 1]; + pixel_pointer.copy_from(src.as_ptr().offset(read_index as isize), 2); } } } diff --git a/ctru-rs/src/error.rs b/ctru-rs/src/error.rs index 5d1d28c..3231c4e 100644 --- a/ctru-rs/src/error.rs +++ b/ctru-rs/src/error.rs @@ -55,6 +55,8 @@ pub enum Error { Libc(String), ServiceAlreadyActive, OutputAlreadyRedirected, + /// The first member is the length of the buffer provided by the user, the second parameter is the size of the requested data (in bytes). + BufferTooShort(usize, usize), } impl Error { @@ -101,6 +103,7 @@ impl fmt::Debug for Error { Self::Libc(err) => f.debug_tuple("Libc").field(err).finish(), Self::ServiceAlreadyActive => f.debug_tuple("ServiceAlreadyActive").finish(), Self::OutputAlreadyRedirected => f.debug_tuple("OutputAlreadyRedirected").finish(), + Self::BufferTooShort(provided, wanted) => f.debug_tuple("BufferTooShort").field(provided).field(wanted).finish(), } } } @@ -110,7 +113,7 @@ impl fmt::Display for Error { match self { &Self::Os(err) => write!( f, - "libctru result code 0x{err:08X}: [{} {}] {}: {}", + "Libctru result code 0x{err:08X}: [{} {}] {}: {}", result_code_level_str(err), result_code_module_str(err), result_code_summary_str(err), @@ -119,8 +122,9 @@ impl fmt::Display for Error { Self::Libc(err) => write!(f, "{err}"), Self::ServiceAlreadyActive => write!(f, "Service already active"), Self::OutputAlreadyRedirected => { - write!(f, "output streams are already redirected to 3dslink") + write!(f, "Output streams are already redirected to 3dslink") } + Self::BufferTooShort(provided, wanted) => write!(f, "The provided buffer's length is too short (length = {provided}) to hold the wanted data (size = {wanted})") } } } diff --git a/ctru-rs/src/services/cam.rs b/ctru-rs/src/services/cam.rs index 43ecbc9..4e222e0 100644 --- a/ctru-rs/src/services/cam.rs +++ b/ctru-rs/src/services/cam.rs @@ -3,7 +3,7 @@ //! The CAM service provides access to the cameras. Cameras can return 2D images //! in the form of byte vectors which can be used for display or other usages. -use crate::error::ResultCode; +use crate::error::{Error, ResultCode}; use crate::services::gspgpu::FramebufferFormat; use bitflags::bitflags; use ctru_sys::Handle; @@ -710,10 +710,6 @@ pub trait Camera { /// /// This will error if the camera is busy or if the timeout duration is reached. /// - /// # Panics - /// - /// This function will panic if `buffer.len() < (width * height * 2)`. - /// /// # Arguments /// /// * `width` - Width of the desired image @@ -745,9 +741,9 @@ pub trait Camera { ))?; }; - let screen_size = u32::from(width) * u32::from(height) * 2; + let screen_size: usize = usize::from(width) * usize::from(height) * 2; if buffer.len() < screen_size as usize { - panic!("Provided buffer's length is shorter than the desired width and height matrix.") + return Err(Error::BufferTooShort(buffer.len(), screen_size)) } unsafe { @@ -760,9 +756,9 @@ pub trait Camera { let mut completion_handle: Handle = 0; ResultCode(ctru_sys::CAMU_SetReceiving( &mut completion_handle, - buffer.as_mut_ptr() as *mut ::libc::c_void, + buffer.as_mut_ptr().cast(), self.port_as_raw(), - screen_size, + screen_size as u32, transfer_unit.try_into().unwrap(), ))?; Ok::(completion_handle)