From 4f7092be8a31687a339e91d5398a54f12c1fb1d9 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Mon, 21 Feb 2022 15:32:24 -0500 Subject: [PATCH] file: remove more implicit string conversions The file info types are now constructed directly from a `&CStr16` instead of internally converting from a `&str`. https://github.com/rust-osdev/uefi-rs/issues/73 --- src/proto/media/file/info.rs | 50 ++++++++++++++---------------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/src/proto/media/file/info.rs b/src/proto/media/file/info.rs index 3a534dbfd..fdd4ced3a 100644 --- a/src/proto/media/file/info.rs +++ b/src/proto/media/file/info.rs @@ -2,7 +2,6 @@ use super::FileAttribute; use crate::data_types::{chars::NUL_16, Align}; use crate::table::runtime::Time; use crate::{unsafe_guid, CStr16, Char16, Identify}; -use core::convert::TryInto; use core::ffi::c_void; use core::{cmp, mem, ptr}; @@ -50,9 +49,8 @@ impl
NamedFileProtocolInfo
{ /// /// The structure will be created in-place within the provided storage /// buffer. The buffer must be large enough to hold the data structure, - /// including a null-terminated UCS-2 version of the `name` string. Note - /// that the struct's aligned size might require additional space beyond - /// the header and name. + /// including a null-terminated UCS-2 `name` string. Note that the struct's + /// aligned size might require additional space beyond the header and name. /// /// The buffer must be correctly aligned. You can query the required /// alignment using the `alignment()` method of the `Align` trait that this @@ -61,16 +59,16 @@ impl
NamedFileProtocolInfo
{ fn new_impl<'buf>( storage: &'buf mut [u8], header: Header, - name: &str, + name: &CStr16, ) -> core::result::Result<&'buf mut Self, FileInfoCreationError> { // Make sure that the storage is properly aligned Self::assert_aligned(storage); // Make sure that the storage is large enough for our needs - let name_length_ucs2 = name.chars().count() + 1; - let name_size = name_length_ucs2 * mem::size_of::(); + let name_num_chars = name.as_slice().len(); + let name_num_bytes = name.num_bytes(); // Round up the size of the header and the name to match the alignment. - let info_size = Self::align_size(mem::size_of::
() + name_size); + let info_size = Self::align_size(mem::size_of::
() + name_num_bytes); if storage.len() < info_size { return Err(FileInfoCreationError::InsufficientStorage(info_size)); } @@ -95,18 +93,14 @@ impl
NamedFileProtocolInfo
{ // For more details of wide pointers, see // https://doc.rust-lang.org/nightly/core/ptr/trait.Pointee.html let fat_ptr = - ptr::from_raw_parts_mut::(storage.as_mut_ptr() as *mut (), name_length_ucs2); + ptr::from_raw_parts_mut::(storage.as_mut_ptr() as *mut (), name_num_chars); &mut *fat_ptr }; - debug_assert_eq!(info.name.len(), name_length_ucs2); + debug_assert_eq!(info.name.len(), name_num_chars); // Write down the UCS-2 name before returning the storage reference - for (target, ch) in info.name.iter_mut().zip(name.chars()) { - *target = ch - .try_into() - .map_err(|_| FileInfoCreationError::InvalidChar(ch))?; - } - info.name[name_length_ucs2 - 1] = NUL_16; + info.name.copy_from_slice(name.as_slice()); + debug_assert_eq!(info.name[name_num_chars - 1], NUL_16); Ok(info) } } @@ -136,9 +130,6 @@ pub enum FileInfoCreationError { /// least the indicated buffer size (in bytes). Please remember that using /// a misaligned buffer will cause a decrease of usable storage capacity. InsufficientStorage(usize), - - /// The suggested file name contains invalid code points (not in UCS-2) - InvalidChar(char), } /// Generic file information @@ -179,9 +170,8 @@ impl FileInfo { /// /// The structure will be created in-place within the provided storage /// buffer. The buffer must be large enough to hold the data structure, - /// including a null-terminated UCS-2 version of the `name` string. Note - /// that the struct's aligned size might require additional space beyond - /// the header and name. + /// including a null-terminated UCS-2 `name` string. Note that the struct's + /// aligned size might require additional space beyond the header and name. /// /// The buffer must be correctly aligned. You can query the required /// alignment using the `alignment()` method of the `Align` trait that this @@ -195,7 +185,7 @@ impl FileInfo { last_access_time: Time, modification_time: Time, attribute: FileAttribute, - file_name: &str, + file_name: &CStr16, ) -> core::result::Result<&'buf mut Self, FileInfoCreationError> { let header = FileInfoHeader { size: 0, @@ -274,9 +264,8 @@ impl FileSystemInfo { /// /// The structure will be created in-place within the provided storage /// buffer. The buffer must be large enough to hold the data structure, - /// including a null-terminated UCS-2 version of the `name` string. Note - /// that the struct's aligned size might require additional space beyond - /// the header and name. + /// including a null-terminated UCS-2 `name` string. Note that the struct's + /// aligned size might require additional space beyond the header and name. /// /// The buffer must be correctly aligned. You can query the required /// alignment using the `alignment()` method of the `Align` trait that this @@ -288,7 +277,7 @@ impl FileSystemInfo { volume_size: u64, free_space: u64, block_size: u32, - volume_label: &str, + volume_label: &CStr16, ) -> core::result::Result<&'buf mut Self, FileInfoCreationError> { let header = FileSystemInfoHeader { size: 0, @@ -346,16 +335,15 @@ impl FileSystemVolumeLabel { /// /// The structure will be created in-place within the provided storage /// buffer. The buffer must be large enough to hold the data structure, - /// including a null-terminated UCS-2 version of the `name` string. Note - /// that the struct's aligned size might require additional space beyond - /// the header and name. + /// including a null-terminated UCS-2 `name` string. Note that the struct's + /// aligned size might require additional space beyond the header and name. /// /// The buffer must be correctly aligned. You can query the required /// alignment using the `alignment()` method of the `Align` trait that this /// struct implements. pub fn new<'buf>( storage: &'buf mut [u8], - volume_label: &str, + volume_label: &CStr16, ) -> core::result::Result<&'buf mut Self, FileInfoCreationError> { let header = FileSystemVolumeLabelHeader {}; Self::new_impl(storage, header, volume_label)