diff --git a/docs/api.rst b/docs/api.rst index 1a3893a0b..2f669d228 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -223,6 +223,7 @@ see details at :ref:`owned_types_concept` .. c:type:: z_moved_bytes_writter_t .. autoctype:: types.h::z_bytes_reader_t +.. autoctype:: types.h::z_bytes_slice_iterator_t Functions ^^^^^^^^^ @@ -241,6 +242,10 @@ Functions .. autocfunction:: primitives.h::z_bytes_to_slice .. autocfunction:: primitives.h::z_bytes_to_string +.. autocfunction:: primitives.h::z_bytes_get_contiguous_view +.. autocfunction:: primitives.h::z_bytes_get_slice_iterator +.. autocfunction:: primitives.h::z_bytes_slice_iterator_next + .. autocfunction:: primitives.h::z_bytes_get_reader .. autocfunction:: primitives.h::z_bytes_reader_read .. autocfunction:: primitives.h::z_bytes_reader_remaining diff --git a/include/zenoh-pico/api/primitives.h b/include/zenoh-pico/api/primitives.h index 3da9ab8f0..af4d45c21 100644 --- a/include/zenoh-pico/api/primitives.h +++ b/include/zenoh-pico/api/primitives.h @@ -457,7 +457,7 @@ z_result_t z_slice_from_buf(z_owned_slice_t *slice, uint8_t *data, size_t len, * Return: * ``0`` if creation is successful, ``negative value`` otherwise. */ -z_result_t z_view_slice_from_buf(z_view_slice_t *slice, uint8_t *data, size_t len); +z_result_t z_view_slice_from_buf(z_view_slice_t *slice, const uint8_t *data, size_t len); /** * Builds an empty :c:type:`z_owned_slice_t`. @@ -685,6 +685,23 @@ size_t z_bytes_len(const z_loaned_bytes_t *bytes); */ bool z_bytes_is_empty(const z_loaned_bytes_t *bytes); +#if defined(Z_FEATURE_UNSTABLE_API) +/** + * Attempts to get a contiguous view to the underlying bytes (unstable). + * + * 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()`. + * + * Parameters: + * bytes: An instance of Zenoh data. + * view: An uninitialized memory location where a contiguous view on data will be constructed. + * + * Return: + * ``0`` in case of success, ``negative value`` otherwise. + */ +z_result_t z_bytes_get_contiguous_view(const z_loaned_bytes_t *bytes, z_view_slice_t *view); +#endif + /** * Returns an iterator on raw bytes slices contained in the `z_loaned_bytes_t`. * diff --git a/src/api/api.c b/src/api/api.c index 4def12579..dc604dedc 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -235,7 +235,7 @@ z_result_t z_slice_from_buf(z_owned_slice_t *slice, uint8_t *data, size_t len, return _Z_RES_OK; } -z_result_t z_view_slice_from_buf(z_view_slice_t *slice, uint8_t *data, size_t len) { +z_result_t z_view_slice_from_buf(z_view_slice_t *slice, const uint8_t *data, size_t len) { slice->_val = _z_slice_alias_buf(data, len); return _Z_RES_OK; } @@ -355,6 +355,22 @@ z_bytes_slice_iterator_t z_bytes_get_slice_iterator(const z_loaned_bytes_t *byte return (z_bytes_slice_iterator_t){._bytes = bytes, ._slice_idx = 0}; } +#if defined(Z_FEATURE_UNSTABLE_API) +z_result_t z_bytes_get_contiguous_view(const z_loaned_bytes_t *bytes, z_view_slice_t *view) { + size_t num_slices = _z_bytes_num_slices(bytes); + if (num_slices > 1) { + return _Z_ERR_INVALID; + } else if (num_slices == 1) { + _z_arc_slice_t *slice = _z_bytes_get_slice(bytes, 0); + z_view_slice_from_buf(view, _z_arc_slice_data(slice), _z_arc_slice_len(slice)); + return _Z_RES_OK; + } else { + z_view_slice_empty(view); + return _Z_RES_OK; + } +} +#endif + bool z_bytes_slice_iterator_next(z_bytes_slice_iterator_t *iter, z_view_slice_t *out) { if (iter->_slice_idx >= _z_bytes_num_slices(iter->_bytes)) { return false; diff --git a/tests/z_api_bytes_test.c b/tests/z_api_bytes_test.c index 0f446943f..d49ad87bc 100644 --- a/tests/z_api_bytes_test.c +++ b/tests/z_api_bytes_test.c @@ -234,15 +234,18 @@ 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_bytes_writer_loan_mut(&writer), data, 10); - z_bytes_writer_finish(z_bytes_writer_move(&writer), &payload); - + z_bytes_copy_from_buf(&payload, data, 10); assert(check_slice(z_bytes_loan(&payload), data, 10)); +#if defined(Z_FEATURE_UNSTABLE_API) + z_view_slice_t view; + assert(z_bytes_get_contiguous_view(z_bytes_loan(&payload), &view) == Z_OK); + assert(z_slice_len(z_view_slice_loan(&view)) == 10); + assert(memcmp(data, z_slice_data(z_view_slice_loan(&view)), 10) == 0); +#endif z_bytes_drop(z_bytes_move(&payload)); + + z_owned_bytes_writer_t writer; z_bytes_writer_empty(&writer); // possible multiple slices @@ -255,6 +258,9 @@ void test_slices(void) { z_bytes_writer_finish(z_bytes_writer_move(&writer), &payload); assert(check_slice(z_bytes_loan(&payload), data, 10)); +#if defined(Z_FEATURE_UNSTABLE_API) + assert(z_bytes_get_contiguous_view(z_bytes_loan(&payload), &view) != Z_OK); +#endif z_bytes_drop(z_bytes_move(&payload)); }