summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-04-10 05:58:19 +0000
committerGitHub <noreply@github.com>2021-04-10 05:58:19 +0000
commitc14ed2106fb04d56d43d1ddb3b92cf8381f1b14b (patch)
tree304e5b60a77f980b1be678c2f8041a3501cc9599
parent86ff8903d8094dcc6361011f83c98dfec0d9a14e (diff)
parentaf8a45d279c4590ddb08b7c37bba7a22557908eb (diff)
downloadrust-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.rs40
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