Skip to content

Commit

Permalink
Merge pull request #629 from DenisBiryukov91/add-bytes-slice-iterator
Browse files Browse the repository at this point in the history
add functionality to iterate over z_bytes slices
  • Loading branch information
milyin authored Sep 6, 2024
2 parents 10ddde2 + 7247df7 commit 2784fca
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 2 deletions.
7 changes: 7 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Data Structures
.. autoctype:: types.h::zp_send_join_options_t
.. autoctype:: types.h::z_bytes_reader_t
.. autoctype:: types.h::z_bytes_iterator_t
.. autoctype:: types.h::z_bytes_slice_iterator_t
.. autoctype:: types.h::z_bytes_writer_t


Expand Down Expand Up @@ -204,6 +205,10 @@ TODO: view type description
Represents a string without null-terminator.

.. c:type:: z_view_slice_t
Represents an array of bytes.

.. c:type:: z_view_keyexpr_t
Represents a key expression in Zenoh.
Expand Down Expand Up @@ -353,6 +358,8 @@ Primitives
.. autocfunction:: primitives.h::z_bytes_is_empty
.. autocfunction:: primitives.h::z_bytes_get_iterator
.. autocfunction:: primitives.h::z_bytes_iterator_next
.. 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_read_bounded
Expand Down
4 changes: 4 additions & 0 deletions include/zenoh-pico/api/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
z_owned_sample_t : z_sample_loan, \
z_owned_query_t : z_query_loan, \
z_owned_slice_t : z_slice_loan, \
z_view_slice_t : z_view_slice_loan, \
z_owned_bytes_t : z_bytes_loan, \
z_owned_encoding_t : z_encoding_loan, \
z_owned_task_t : z_task_loan, \
Expand Down Expand Up @@ -83,6 +84,7 @@
z_owned_sample_t : z_sample_loan_mut, \
z_owned_query_t : z_query_loan_mut, \
z_owned_slice_t : z_slice_loan_mut, \
z_view_slice_t : z_view_slice_loan_mut, \
z_owned_bytes_t : z_bytes_loan_mut, \
z_owned_task_t : z_task_loan_mut, \
z_owned_mutex_t : z_mutex_loan_mut, \
Expand Down Expand Up @@ -381,6 +383,7 @@ inline const z_loaned_string_array_t* z_loan(const z_owned_string_array_t& x) {
inline const z_loaned_sample_t* z_loan(const z_owned_sample_t& x) { return z_sample_loan(&x); }
inline const z_loaned_query_t* z_loan(const z_owned_query_t& x) { return z_query_loan(&x); }
inline const z_loaned_slice_t* z_loan(const z_owned_slice_t& x) { return z_slice_loan(&x); }
inline const z_loaned_slice_t* z_loan(const z_view_slice_t& x) { return z_view_slice_loan(&x); }
inline const z_loaned_bytes_t* z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); }
inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t& x) { return z_encoding_loan(&x); }
inline const z_loaned_task_t* z_loan(const z_owned_task_t& x) { return z_task_loan(&x); }
Expand Down Expand Up @@ -410,6 +413,7 @@ inline z_loaned_reply_t* z_loan_mut(z_owned_reply_t& x) { return z_reply_loan_mu
inline z_loaned_hello_t* z_loan_mut(z_owned_hello_t& x) { return z_hello_loan_mut(&x); }
inline z_loaned_string_t* z_loan_mut(z_owned_string_t& x) { return z_string_loan_mut(&x); }
inline z_loaned_string_t* z_loan_mut(z_view_string_t& x) { return z_view_string_loan_mut(&x); }
inline z_loaned_slice_t* z_loan_mut(z_view_slice_t& x) { return z_view_slice_loan_mut(&x); }
inline z_loaned_string_array_t* z_loan_mut(z_owned_string_array_t& x) { return z_string_array_loan_mut(&x); }
inline z_loaned_sample_t* z_loan_mut(z_owned_sample_t& x) { return z_sample_loan_mut(&x); }
inline z_loaned_query_t* z_loan_mut(z_owned_query_t& x) { return z_query_loan_mut(&x); }
Expand Down
31 changes: 30 additions & 1 deletion include/zenoh-pico/api/primitives.h
Original file line number Diff line number Diff line change
Expand Up @@ -987,12 +987,40 @@ z_bytes_iterator_t z_bytes_get_iterator(const z_loaned_bytes_t *bytes);
*
* Parameters:
* iter: An iterator over multi-element serialized data.
* out: An uninitialized :c:type:`z_owned_bytes_t` that will contained next serialized element.
* out: An uninitialized :c:type:`z_owned_bytes_t` that will contain next serialized element.
* Return:
* ``false`` when iterator reaches the end, ``true`` otherwise.
*/
_Bool z_bytes_iterator_next(z_bytes_iterator_t *iter, z_owned_bytes_t *out);

/**
* Returns an iterator on raw bytes slices contained in the `z_loaned_bytes_t`.
*
* Zenoh may store data in non-contiguous regions of memory, this iterator
* then allows to access raw data directly without any attempt of deserializing it.
* Please note that no guarantee is provided on the internal memory layout.
* The only provided guarantee is on the bytes order that is preserved.
*
* Parameters:
* bytes: Data to iterate over.
*
* Return:
* The constructed :c:type:`z_bytes_slice_iterator_t`.
*/
z_bytes_slice_iterator_t z_bytes_get_slice_iterator(const z_loaned_bytes_t *bytes);

/**
* Constructs :c:type:`z_view_slice_t` providing view to the next slice.
*
*
* Parameters:
* iter: An iterator over slices of serialized data.
* out: An uninitialized :c:type:`z_view_slice_t` that will contain next slice.
* Return:
* ``false`` when iterator reaches the end, ``true`` otherwise.
*/
_Bool z_bytes_slice_iterator_next(z_bytes_slice_iterator_t *iter, z_view_slice_t *out);

/**
* Returns a reader for the `bytes`.
*
Expand Down Expand Up @@ -1352,6 +1380,7 @@ _Z_OWNED_FUNCTIONS_CLOSURE_DEF(closure_zid)

_Z_VIEW_FUNCTIONS_DEF(keyexpr)
_Z_VIEW_FUNCTIONS_DEF(string)
_Z_VIEW_FUNCTIONS_DEF(slice)

/**
* Loans a :c:type:`z_owned_sample_t`.
Expand Down
9 changes: 9 additions & 0 deletions include/zenoh-pico/api/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef _z_timestamp_t z_timestamp_t;
* uint8_t *start: A pointer to the bytes array.
*/
_Z_OWNED_TYPE_VALUE(_z_slice_t, slice)
_Z_VIEW_TYPE(_z_slice_t, slice)

/**
* Represents a container for slices.
Expand All @@ -85,6 +86,14 @@ typedef _z_bytes_iterator_t z_bytes_iterator_t;
*/
typedef _z_bytes_iterator_t z_bytes_reader_t;

/**
* An iterator over slices of serialized data.
*/
typedef struct {
const _z_bytes_t *_bytes;
size_t _slice_idx;
} z_bytes_slice_iterator_t;

/**
* Represents a string without null-terminator.
*
Expand Down
15 changes: 15 additions & 0 deletions src/api/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,20 @@ _Bool z_bytes_iterator_next(z_bytes_iterator_t *iter, z_owned_bytes_t *bytes) {
return true;
}

z_bytes_slice_iterator_t z_bytes_get_slice_iterator(const z_loaned_bytes_t *bytes) {
return (z_bytes_slice_iterator_t){._bytes = bytes, ._slice_idx = 0};
}

_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;
}
const _z_arc_slice_t *arc_slice = _z_bytes_get_slice(iter->_bytes, iter->_slice_idx);
out->_val = _z_slice_alias_buf(_Z_RC_IN_VAL(&arc_slice->slice)->start + arc_slice->start, arc_slice->len);
iter->_slice_idx++;
return true;
}

z_bytes_writer_t z_bytes_get_writer(z_loaned_bytes_t *bytes) {
return _z_bytes_get_iterator_writer(bytes, Z_IOSLICE_SIZE);
}
Expand Down Expand Up @@ -762,6 +776,7 @@ _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_keyexpr_t, keyexpr, _z_keyexpr_check, _z_keyexp
_z_keyexpr_clear)
_Z_VIEW_FUNCTIONS_IMPL(_z_keyexpr_t, keyexpr, _z_keyexpr_check, _z_keyexpr_null)
_Z_VIEW_FUNCTIONS_IMPL(_z_string_t, string, _z_string_check, _z_string_null)
_Z_VIEW_FUNCTIONS_IMPL(_z_slice_t, slice, _z_slice_check, _z_slice_empty)

_Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_hello_t, hello, _z_hello_check, _z_hello_null, _z_hello_copy, _z_hello_clear)

Expand Down
44 changes: 44 additions & 0 deletions tests/z_api_bytes_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,49 @@ void test_pair(void) {
assert(d == 123.45);
}

_Bool check_slice(const z_loaned_bytes_t *b, const uint8_t *data, size_t len) {
z_bytes_slice_iterator_t it = z_bytes_get_slice_iterator(b);
uint8_t *data_out = (uint8_t *)malloc(len);
z_view_slice_t v;
size_t pos = 0;
while (z_bytes_slice_iterator_next(&it, &v)) {
const uint8_t *slice_data = z_slice_data(z_view_slice_loan(&v));
size_t slice_len = z_slice_len(z_view_slice_loan(&v));
memcpy(data_out + pos, slice_data, slice_len);
pos += slice_len;
}
assert(pos == len);
assert(memcmp(data, data_out, len) == 0);
free(data_out);
return true;
}

void test_slices(void) {
uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
z_owned_bytes_t payload;
z_bytes_empty(&payload);

z_bytes_writer_t writer = z_bytes_get_writer(z_bytes_loan_mut(&payload));
z_bytes_writer_write_all(&writer, data, 10);

assert(check_slice(z_bytes_loan(&payload), data, 10));

z_bytes_drop(z_bytes_move(&payload));
z_bytes_empty(&payload);

// possible multiple slices
writer = z_bytes_get_writer(z_bytes_loan_mut(&payload));

for (size_t i = 0; i < 10; i++) {
z_owned_bytes_t b;
z_bytes_serialize_from_buf(&b, data + i, 1);
z_bytes_writer_append(&writer, z_bytes_move(&b));
}

assert(check_slice(z_bytes_loan(&payload), data, 10));
z_bytes_drop(z_bytes_move(&payload));
}

int main(void) {
test_reader_seek();
test_reader_read();
Expand All @@ -309,4 +352,5 @@ int main(void) {
test_append();
test_iter();
test_pair();
test_slices();
}
2 changes: 1 addition & 1 deletion zenohpico.pc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ prefix=/usr/local
Name: zenohpico
Description:
URL:
Version: 1.0.20240830dev
Version: 1.0.20240905dev
Cflags: -I${prefix}/include
Libs: -L${prefix}/lib -lzenohpico

0 comments on commit 2784fca

Please sign in to comment.