diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-10 05:58:19 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-10 05:58:19 +0000 |
commit | c14ed2106fb04d56d43d1ddb3b92cf8381f1b14b (patch) | |
tree | 304e5b60a77f980b1be678c2f8041a3501cc9599 | |
parent | 86ff8903d8094dcc6361011f83c98dfec0d9a14e (diff) | |
parent | af8a45d279c4590ddb08b7c37bba7a22557908eb (diff) | |
download | rust-libzfs-c14ed2106fb04d56d43d1ddb3b92cf8381f1b14b.zip |
Merge #57
57: add wrappers for nvlist_pack/unpack r=jmesmon a=ahrens
Add wrappers for nvlist_pack() and nvlist_unpack().
I'm a bit new to Rust but I tried to follow the examples in this file. Please let me know if this could be more idiomatic.
Closes #56
Co-authored-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 |