1 use core::cmp; 2 use core::convert::TryFrom; 3 use crate::error::*; 4 use crate::flag::*; 5 6 /// Helper for seek calls 7 /// In most cases it's easier to use a usize to track the offset and buffer size internally, 8 /// but the seek interface uses isize. This wrapper ensures EOVERFLOW errors are returned 9 /// as appropriate if the value in the usize can't fit in the isize. 10 pub fn calc_seek_offset_usize(cur_offset: usize, pos: isize, whence: usize, buf_len: usize) -> Result<isize> { 11 let cur_offset = isize::try_from(cur_offset).or_else(|_| Err(Error::new(EOVERFLOW)))?; 12 let buf_len = isize::try_from(buf_len).or_else(|_| Err(Error::new(EOVERFLOW)))?; 13 calc_seek_offset_isize(cur_offset, pos, whence, buf_len) 14 } 15 16 /// Helper for seek calls 17 /// Result is guaranteed to be positive. 18 /// EOVERFLOW returned if the arguments would cause an overflow. 19 /// EINVAL returned if the new offset is out of bounds. 20 pub fn calc_seek_offset_isize(cur_offset: isize, pos: isize, whence: usize, buf_len: isize) -> Result<isize> { 21 let new_offset = match whence { 22 SEEK_CUR => pos.checked_add(cur_offset), 23 SEEK_END => pos.checked_add(buf_len), 24 SEEK_SET => Some(pos), 25 _ => None, 26 }; 27 28 match new_offset { 29 Some(new_offset) if new_offset < 0 => Err(Error::new(EINVAL)), 30 Some(new_offset) => Ok(cmp::min(new_offset, buf_len)), 31 None => Err(Error::new(EOVERFLOW)) rm_rf(const char * dir)32 } 33 }