Skip to content

Commit

Permalink
file: remove more implicit string conversions
Browse files Browse the repository at this point in the history
The file info types are now constructed directly from a `&CStr16`
instead of internally converting from a `&str`.

rust-osdev#73
  • Loading branch information
nicholasbishop committed Feb 21, 2022
1 parent e09f170 commit 4f7092b
Showing 1 changed file with 19 additions and 31 deletions.
50 changes: 19 additions & 31 deletions src/proto/media/file/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -50,9 +49,8 @@ impl<Header> NamedFileProtocolInfo<Header> {
///
/// 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
Expand All @@ -61,16 +59,16 @@ impl<Header> NamedFileProtocolInfo<Header> {
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::<Char16>();
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::<Header>() + name_size);
let info_size = Self::align_size(mem::size_of::<Header>() + name_num_bytes);
if storage.len() < info_size {
return Err(FileInfoCreationError::InsufficientStorage(info_size));
}
Expand All @@ -95,18 +93,14 @@ impl<Header> NamedFileProtocolInfo<Header> {
// 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::<Self>(storage.as_mut_ptr() as *mut (), name_length_ucs2);
ptr::from_raw_parts_mut::<Self>(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)
}
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 4f7092b

Please sign in to comment.