use crate::{Result, U16CStr};
use std::ffi::OsStr;
use std::iter;
use std::os::windows::ffi::OsStrExt;
use windows::Win32::Foundation::STATUS_INSUFFICIENT_RESOURCES;
pub trait WideNameInfoInternal<const BUFFER_SIZE: usize = 255>:
crate::filesystem::sealed::Sealed
{
#[doc(hidden)]
fn name_buffer(&mut self) -> &mut [u16; BUFFER_SIZE];
#[doc(hidden)]
fn set_size(&mut self, buffer_size: u16);
#[doc(hidden)]
fn add_to_buffer_internal(entry: Option<&Self>, buffer: &mut [u8], cursor: &mut u32) -> bool;
}
pub trait WideNameInfo<const BUFFER_SIZE: usize = 255>:
crate::filesystem::sealed::Sealed + WideNameInfoInternal<BUFFER_SIZE>
{
fn finalize_buffer(buffer: &mut [u8], cursor: &mut u32) -> bool {
Self::add_to_buffer_internal(None, buffer, cursor)
}
fn append_to_buffer(&self, buffer: &mut [u8], cursor: &mut u32) -> bool {
Self::add_to_buffer_internal(Some(self), buffer, cursor)
}
fn reset(&mut self);
fn set_name_raw<'a, P: Into<&'a [u16]>>(&mut self, file_name: P) -> Result<()> {
let file_name = file_name.into();
if file_name.len() > BUFFER_SIZE {
return Err(STATUS_INSUFFICIENT_RESOURCES.into());
}
self.name_buffer()[0..std::cmp::min(file_name.len(), BUFFER_SIZE)]
.copy_from_slice(&file_name[0..std::cmp::min(file_name.len(), BUFFER_SIZE)]);
self.set_size(std::mem::size_of_val(file_name) as u16);
Ok(())
}
fn set_name<P: AsRef<OsStr>>(&mut self, file_name: P) -> Result<()> {
let file_name = file_name.as_ref();
let file_name = file_name
.encode_wide()
.chain(iter::once(0))
.collect::<Vec<_>>();
self.set_name_raw(file_name.as_slice())
}
fn set_name_cstr<P: AsRef<U16CStr>>(&mut self, file_name: P) -> Result<()> {
let file_name = file_name.as_ref();
self.set_name_raw(file_name.as_slice_with_nul())
}
}