diff options
author | Matthew Ahrens <mahrens@delphix.com> | 2021-04-08 22:55:51 -0700 |
---|---|---|
committer | Matthew Ahrens <mahrens@delphix.com> | 2021-04-09 10:09:53 -0700 |
commit | af8a45d279c4590ddb08b7c37bba7a22557908eb (patch) | |
tree | 304e5b60a77f980b1be678c2f8041a3501cc9599 | |
parent | 86ff8903d8094dcc6361011f83c98dfec0d9a14e (diff) | |
download | rust-libzfs-af8a45d279c4590ddb08b7c37bba7a22557908eb.zip |
add wrappers for nvlist_pack/unpack
Signed-off-by: Matthew Ahrens <mahrens@delphix.com>
-rw-r--r-- | nvpair/src/lib.rs | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/nvpair/src/lib.rs b/nvpair/src/lib.rs index feb22aa..b9ab6fc 100644 --- a/nvpair/src/lib.rs +++ b/nvpair/src/lib.rs @@ -123,7 +123,7 @@ impl NvEncode for str { } } -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub enum NvEncoding { Native, Xdr, @@ -178,6 +178,20 @@ impl NvList { } } + /// Try to create a new `NvList` from the packed buffer + /// + /// Returns an error if memory allocation fails + pub fn try_unpack(buf: &[u8]) -> io::Result<Self> { + let mut n = ptr::null_mut(); + let len_u64 = buf.len() as u64; + let v = unsafe { nvpair_sys::nvlist_unpack(buf.as_ptr() as *mut _, len_u64, &mut n, 0) }; + if v != 0 { + Err(io::Error::from_raw_os_error(v)) + } else { + Ok(unsafe { Self::from_ptr(n) }) + } + } + /// Create a new `NvList` with no options /// /// # Panics @@ -255,6 +269,30 @@ impl NvListRef { } } + pub fn pack(&self, code: NvEncoding) -> io::Result<Vec<u8>> { + let size = self.encoded_size(code).unwrap() as usize; + let mut vec = Vec::with_capacity(size); + let mut cap = vec.capacity() as u64; + let mut ptr = vec.as_mut_ptr() as *mut i8; + + let v = unsafe { + let v = nvpair_sys::nvlist_pack( + self.as_ptr() as *mut _, + &mut ptr, + &mut cap, + code.as_raw(), + 0, + ); + vec.set_len(cap as usize); + v + }; + if v != 0 { + Err(io::Error::from_raw_os_error(v)) + } else { + Ok(vec) + } + } + pub fn is_empty(&self) -> bool { let v = unsafe { sys::nvlist_empty(self.as_ptr() as *mut _) }; v != sys::boolean_t::B_FALSE |