use std::io;
use std::mem::MaybeUninit;
pub fn extract_noattr(result: io::Result<Vec<u8>>) -> io::Result<Option<Vec<u8>>> {
result.map(Some).or_else(|e| {
if e.raw_os_error() == Some(crate::sys::ENOATTR) {
Ok(None)
} else {
Err(e)
}
})
}
#[allow(dead_code)]
pub fn allocate_loop<F, S>(mut get_value: F, mut get_size: S) -> io::Result<Vec<u8>>
where
F: for<'a> FnMut(&'a mut [MaybeUninit<u8>]) -> io::Result<&'a mut [u8]>,
S: FnMut() -> io::Result<usize>,
{
const INITIAL_BUFFER_SIZE: usize = 4096;
match get_value(&mut [MaybeUninit::<u8>::uninit(); INITIAL_BUFFER_SIZE]) {
Ok(val) => return Ok(val.to_vec()),
Err(e) if e.raw_os_error() != Some(crate::sys::ERANGE) => return Err(e),
_ => {}
}
let mut vec: Vec<u8> = Vec::new();
loop {
vec.reserve_exact(get_size()?);
match get_value(vec.spare_capacity_mut()) {
Ok(initialized) => {
unsafe {
let len = initialized.len();
assert_eq!(
initialized.as_ptr(),
vec.as_ptr(),
"expected the same buffer"
);
vec.set_len(len);
}
if vec.capacity() > vec.len() + 1 {
vec.shrink_to_fit();
}
return Ok(vec);
}
Err(e) if e.raw_os_error() != Some(crate::sys::ERANGE) => return Err(e),
_ => {} }
}
}