diff --git a/docs/api.rst b/docs/api.rst index e1e2a063d..468073a91 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -280,6 +280,7 @@ Types .. doxygenstruct:: z_bytes_reader_t .. doxygenstruct:: z_owned_bytes_writer_t .. doxygenstruct:: z_loaned_bytes_writer_t +.. doxygenstruct:: z_bytes_slice_iterator_t Functions ^^^^^^^^^ @@ -303,6 +304,10 @@ Functions .. doxygenfunction:: z_bytes_loan_mut .. doxygenfunction:: z_bytes_drop +.. doxygenfunction:: z_bytes_get_slice_iterator +.. doxygenfunction:: z_bytes_slice_iterator_next +.. doxygenfunction:: z_bytes_get_contiguous_view + .. doxygenfunction:: z_bytes_get_reader .. doxygenfunction:: z_bytes_reader_read .. doxygenfunction:: z_bytes_reader_seek diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index fdb80aeba..983a941de 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1540,6 +1540,18 @@ z_result_t z_bytes_from_str(struct z_owned_bytes_t *this_, * The string is consumed upon function return. */ ZENOHC_API void z_bytes_from_string(struct z_owned_bytes_t *this_, struct z_moved_string_t *s); +/** + * Attempts to get a contiguous view to the underlying bytes. + * This is only possible if data is not fragmented, otherwise the function will fail. + * In case of fragmented data, consider using `z_bytes_get_slice_iterator()`. + * + * @param this_: an instance of Zenoh data. + * @param view: An unitialized memory location where a contiguous view on data will be constructed. + * @return ​0​ upon success, negative error code otherwise. + */ +ZENOHC_API +z_result_t z_bytes_get_contiguous_view(const struct z_loaned_bytes_t *this_, + struct z_view_slice_t *view); /** * Returns a reader for the data. * diff --git a/src/zbytes.rs b/src/zbytes.rs index 5cc2eb874..cacae6050 100644 --- a/src/zbytes.rs +++ b/src/zbytes.rs @@ -479,6 +479,29 @@ pub extern "C" fn z_bytes_slice_iterator_next( } } +/// Attempts to get a contiguous view to the underlying bytes. +/// This is only possible if data is not fragmented, otherwise the function will fail. +/// In case of fragmented data, consider using `z_bytes_get_slice_iterator()`. +/// +/// @param this_: an instance of Zenoh data. +/// @param view: An unitialized memory location where a contiguous view on data will be constructed. +/// @return ​0​ upon success, negative error code otherwise. +#[no_mangle] +pub extern "C" fn z_bytes_get_contiguous_view( + this: &'static z_loaned_bytes_t, + view: &mut MaybeUninit, +) -> result::z_result_t { + let payload = this.as_rust_type_ref(); + match payload.to_bytes() { + std::borrow::Cow::Borrowed(s) => { + view.as_rust_type_mut_uninit() + .write(CSliceView::from_slice(s)); + result::Z_OK + } + std::borrow::Cow::Owned(_) => result::Z_EINVAL, + } +} + #[cfg(all(feature = "shared-memory", feature = "unstable"))] /// @warning This API has been marked as unstable: it works as advertised, but it may be changed in a future release. /// @brief Converts from an immutable SHM buffer consuming it. diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c index 745e49389..0e66012a6 100644 --- a/tests/z_api_payload_test.c +++ b/tests/z_api_payload_test.c @@ -231,14 +231,17 @@ bool check_slice(const z_loaned_bytes_t *b, const uint8_t *data, size_t len) { void test_slices(void) { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; z_owned_bytes_t payload; - z_owned_bytes_writer_t writer; - z_bytes_writer_empty(&writer); - z_bytes_writer_write_all(z_loan_mut(writer), data, 10); - z_bytes_writer_finish(z_move(writer), &payload); + z_bytes_copy_from_buf(&payload, data, 10); assert(check_slice(z_loan(payload), data, 10)); + z_view_slice_t view; + assert(z_bytes_get_contiguous_view(z_loan(payload), &view) == Z_OK); + assert(z_slice_len(z_loan(view)) == 10); + assert(memcmp(data, z_slice_data(z_loan(view)), 10) == 0); + z_drop(z_move(payload)); + z_owned_bytes_writer_t writer; // possible multiple slices z_bytes_writer_empty(&writer); @@ -249,6 +252,7 @@ void test_slices(void) { } z_bytes_writer_finish(z_move(writer), &payload); assert(check_slice(z_loan(payload), data, 10)); + assert(z_bytes_get_contiguous_view(z_loan(payload), &view) != Z_OK); z_drop(z_move(payload)); }