tools: add read/write convenience helpers
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
		@ -31,6 +31,8 @@ pub mod tty;
 | 
				
			|||||||
pub mod signalfd;
 | 
					pub mod signalfd;
 | 
				
			||||||
pub mod daemon;
 | 
					pub mod daemon;
 | 
				
			||||||
pub mod procfs;
 | 
					pub mod procfs;
 | 
				
			||||||
 | 
					pub mod read;
 | 
				
			||||||
 | 
					pub mod write;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod process_locker;
 | 
					mod process_locker;
 | 
				
			||||||
pub use process_locker::*;
 | 
					pub use process_locker::*;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										50
									
								
								src/tools/read.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/tools/read.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					//! Utility traits for types which implement `std::io::Read` to quickly read primitively typed
 | 
				
			||||||
 | 
					//! values such as binary integers from a stream.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use std::io;
 | 
				
			||||||
 | 
					use std::mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use endian_trait::Endian;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub trait ReadUtilOps {
 | 
				
			||||||
 | 
					    /// Read a value of type `T`.
 | 
				
			||||||
 | 
					    /// Note that it *should* be `repr(C, packed)` or similar.
 | 
				
			||||||
 | 
					    fn read_value<T>(&mut self) -> io::Result<T>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Read a big-endian value of type `T`.
 | 
				
			||||||
 | 
					    /// Note that it *should* be `repr(C, packed)` or similar.
 | 
				
			||||||
 | 
					    fn read_value_be<T: Endian>(&mut self) -> io::Result<T> {
 | 
				
			||||||
 | 
					        Ok(self.read_value::<T>()?.from_be())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Read a little-endian value of type `T`.
 | 
				
			||||||
 | 
					    /// Note that it *should* be `repr(C, packed)` or similar.
 | 
				
			||||||
 | 
					    fn read_value_le<T: Endian>(&mut self) -> io::Result<T> {
 | 
				
			||||||
 | 
					        Ok(self.read_value::<T>()?.from_le())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Read an exact number of bytes into a newly allocated vector.
 | 
				
			||||||
 | 
					    fn read_exact_allocated(&mut self, size: usize) -> io::Result<Vec<u8>>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<R: io::Read> ReadUtilOps for R {
 | 
				
			||||||
 | 
					    fn read_value<T>(&mut self) -> io::Result<T> {
 | 
				
			||||||
 | 
					        let mut data: T = unsafe { mem::uninitialized() };
 | 
				
			||||||
 | 
					        self.read_exact(unsafe {
 | 
				
			||||||
 | 
					            std::slice::from_raw_parts_mut(
 | 
				
			||||||
 | 
					                &mut data as *mut T as *mut u8,
 | 
				
			||||||
 | 
					                mem::size_of::<T>(),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        })?;
 | 
				
			||||||
 | 
					        Ok(data)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn read_exact_allocated(&mut self, size: usize) -> io::Result<Vec<u8>> {
 | 
				
			||||||
 | 
					        let mut out = Vec::with_capacity(size);
 | 
				
			||||||
 | 
					        unsafe {
 | 
				
			||||||
 | 
					            out.set_len(size);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self.read_exact(&mut out)?;
 | 
				
			||||||
 | 
					        Ok(out)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										43
									
								
								src/tools/write.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/tools/write.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					//! Utility traits for types which implement `std::io::Write` to easily write primitively typed
 | 
				
			||||||
 | 
					//! values such as binary integers to a stream.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use std::io;
 | 
				
			||||||
 | 
					use std::mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use endian_trait::Endian;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub trait WriteUtilOps {
 | 
				
			||||||
 | 
					    /// Write a value of type `T`.
 | 
				
			||||||
 | 
					    /// Note that it *should* be `repr(C, packed)` or similar.
 | 
				
			||||||
 | 
					    fn write_value<T>(&mut self, value: &T) -> io::Result<usize>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Write a big-endian value of type `T`.
 | 
				
			||||||
 | 
					    /// Note that it *should* be `repr(C, packed)` or similar.
 | 
				
			||||||
 | 
					    fn write_value_be<T: Endian>(&mut self, value: T) -> io::Result<usize> {
 | 
				
			||||||
 | 
					        self.write_value(&value.to_be())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Write a little-endian value of type `T`.
 | 
				
			||||||
 | 
					    /// Note that it *should* be `repr(C, packed)` or similar.
 | 
				
			||||||
 | 
					    fn write_value_le<T: Endian>(&mut self, value: T) -> io::Result<usize> {
 | 
				
			||||||
 | 
					        self.write_value(&value.to_le())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Convenience `write_all()` alternative returning the length instead of `()`.
 | 
				
			||||||
 | 
					    fn write_all_len(&mut self, value: &[u8]) -> io::Result<usize>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<R: io::Write> WriteUtilOps for R {
 | 
				
			||||||
 | 
					    fn write_value<T>(&mut self, value: &T) -> io::Result<usize> {
 | 
				
			||||||
 | 
					        let size = mem::size_of::<T>();
 | 
				
			||||||
 | 
					        self.write_all(unsafe {
 | 
				
			||||||
 | 
					            std::slice::from_raw_parts(value as *const T as *const u8, size)
 | 
				
			||||||
 | 
					        })?;
 | 
				
			||||||
 | 
					        Ok(size)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_all_len(&mut self, value: &[u8]) -> io::Result<usize> {
 | 
				
			||||||
 | 
					        self.write_all(value)?;
 | 
				
			||||||
 | 
					        Ok(value.len())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user