Skip to content

Commit

Permalink
z_bytes_to_slice and z_bytes_to_string no longer perform a copy if da…
Browse files Browse the repository at this point in the history
…ta is contiguous
  • Loading branch information
DenisBiryukov91 committed Nov 14, 2024
1 parent 17cfe73 commit 1a7b7f0
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 16 deletions.
35 changes: 21 additions & 14 deletions src/zbytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,8 @@ pub unsafe extern "C" fn z_bytes_to_string(
this: &z_loaned_bytes_t,
dst: &mut MaybeUninit<z_owned_string_t>,
) -> z_result_t {
let payload = this.as_rust_type_ref();
match payload.try_to_string() {
Ok(s) => {
dst.as_rust_type_mut_uninit().write(s.into_owned().into());
result::Z_OK
}
Err(e) => {
tracing::error!("Failed to convert the payload: {}", e);
dst.as_rust_type_mut_uninit().write(CStringOwned::default());
result::Z_EINVAL
}
}
let dst_slice = std::mem::transmute(dst);
z_bytes_to_slice(this, dst_slice)
}

/// Converts data into an owned slice.
Expand All @@ -135,8 +125,25 @@ pub unsafe extern "C" fn z_bytes_to_slice(
dst: &mut MaybeUninit<z_owned_slice_t>,
) -> z_result_t {
let payload = this.as_rust_type_ref();
dst.as_rust_type_mut_uninit()
.write(payload.to_bytes().into_owned().into());
match payload.to_bytes() {
std::borrow::Cow::Borrowed(s) => {
let context = Box::leak(Box::new(payload.clone())) as *mut ZBytes as *mut _;
extern "C" fn __z_drop_bytes_inner(_data: *mut c_void, context: *mut c_void) {
let _ = unsafe { Box::from_raw(context as *mut ZBytes) };
}
let cs = CSliceOwned::wrap(
s.as_ptr() as *mut _,
s.len(),
Some(__z_drop_bytes_inner),
context,
)
.unwrap();
dst.as_rust_type_mut_uninit().write(cs);
}
std::borrow::Cow::Owned(v) => {
dst.as_rust_type_mut_uninit().write(v.into());
}
}
result::Z_OK
}

Expand Down
4 changes: 2 additions & 2 deletions tests/z_api_payload_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ void test_slice(void) {

assert(cnt == 0);
z_drop(z_move(payload));
assert(cnt == 1);


assert(!memcmp(data, z_slice_data(z_loan(out)), 10));
z_slice_drop(z_slice_move(&out));
assert(cnt == 1);

z_owned_bytes_t payload2;
z_owned_slice_t s;
Expand Down

0 comments on commit 1a7b7f0

Please sign in to comment.