From e4f452419fb711c76a42dd51eee6f610b2c9d4bf Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 27 May 2024 17:28:17 +0200 Subject: [PATCH 1/4] added functions for encoding to/decoding from iterator or pair for z_bytes --- docs/api.rst | 4 + examples/z_pub_attachment.c | 45 ++++++--- examples/z_put.c | 14 +-- examples/z_sub_attachment.c | 29 +++--- include/zenoh_commons.h | 39 ++++++++ src/payload.rs | 118 ++++++++++++++++++++++- tests/z_int_pub_sub_attachment_test.c | 96 +++++++++++++------ tests/z_int_queryable_attachment_test.c | 120 ++++++++++++++++-------- 8 files changed, 356 insertions(+), 109 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 64fd25f00..199ab15e1 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -135,9 +135,13 @@ Functions .. doxygenfunction:: z_bytes_encode_from_slice .. doxygenfunction:: z_bytes_encode_from_string .. doxygenfunction:: z_bytes_encode_from_slice_map +.. doxygenfunction:: z_bytes_encode_from_iter +.. doxygenfunction:: z_bytes_encode_from_pair .. doxygenfunction:: z_bytes_decode_into_slice .. doxygenfunction:: z_bytes_decode_into_string .. doxygenfunction:: z_bytes_decode_into_slice_map +.. doxygenfunction:: z_bytes_decode_into_iter +.. doxygenfunction:: z_bytes_decode_into_pair .. doxygenfunction:: z_bytes_clone .. doxygenfunction:: z_bytes_loan diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index 463ebb3aa..8b4defa60 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -16,6 +16,31 @@ #include "zenoh.h" +typedef struct kv_pair_t { + const char* key; + const char* value; +} kv_pair_t; + +typedef struct kv_pairs_t { + const kv_pair_t* data; + size_t len; + size_t current_idx; +} kv_pairs_t; + +void create_attachment_iter(z_owned_bytes_t* kv_pair, void* context) { + kv_pairs_t *kvs = (kv_pairs_t*)(context); + z_owned_bytes_t k, v; + if (kvs->current_idx >= kvs->len) { + z_null(kv_pair); + } else { + z_bytes_encode_from_string(&k, kvs->data[kvs->current_idx].key); + z_bytes_encode_from_string(&v, kvs->data[kvs->current_idx].value); + z_bytes_encode_pair(kv_pair, z_move(k), z_move(v)); + kvs->current_idx++; + } +}; + + int main(int argc, char **argv) { char *keyexpr = "demo/example/zenoh-c-pub"; char *value = "Pub from C!"; @@ -54,14 +79,9 @@ int main(int argc, char **argv) { z_publisher_put_options_t options; z_publisher_put_options_default(&options); - // allocate attachment map - z_owned_slice_map_t map; - z_slice_map_new(&map); - z_view_slice_t src_key, src_value; - z_view_slice_from_str(&src_key, "source"); - z_view_slice_from_str(&src_value, "C"); - // add some value - z_slice_map_insert_by_alias(z_loan_mut(map), z_loan(src_key), z_loan(src_value)); + // allocate attachment data + kv_pair_t kvs[2]; + kvs[0] = (kv_pair_t){ .key = "source", .value = "C" }; // allocate attachment and payload z_owned_bytes_t attachment; z_owned_bytes_t payload; @@ -73,11 +93,9 @@ int main(int argc, char **argv) { // add some other attachment value sprintf(buf_ind, "%d", idx); - z_view_slice_t index_key, index_value; - z_view_slice_from_str(&index_key, "index"); - z_view_slice_from_str(&index_value, buf_ind); - z_slice_map_insert_by_alias(z_loan_mut(map), z_loan(index_key), z_loan(index_value)); - z_bytes_encode_from_slice_map(&attachment, z_loan(map)); + kvs[1] = (kv_pair_t){ .key = "index", .value = buf_ind }; + kv_pairs_t ctx = (kv_pairs_t) { .data = kvs, .current_idx = 0, .len = 2 }; + z_bytes_encode_from_iter(&attachment, create_attachment_iter, (void*)&ctx); options.attachment = &attachment; sprintf(buf, "[%4d] %s", idx, value); @@ -90,7 +108,6 @@ int main(int argc, char **argv) { z_undeclare_publisher(z_move(pub)); z_close(z_move(s)); - z_drop(z_move(map)); return 0; } diff --git a/examples/z_put.c b/examples/z_put.c index 27c2f2925..c395c19b2 100644 --- a/examples/z_put.c +++ b/examples/z_put.c @@ -23,13 +23,6 @@ int main(int argc, char **argv) { if (argc > 1) keyexpr = argv[1]; if (argc > 2) value = argv[2]; - z_owned_slice_map_t attachment_map; - z_slice_map_new(&attachment_map); - z_view_slice_t map_key, map_value; - z_view_slice_from_str(&map_key, "hello"); - z_view_slice_from_str(&map_value, "there"); - z_slice_map_insert_by_alias(z_loan_mut(attachment_map), z_loan(map_key), z_loan(map_value)); - z_owned_config_t config; z_config_default(&config); @@ -58,8 +51,10 @@ int main(int argc, char **argv) { z_owned_bytes_t payload; z_bytes_encode_from_string(&payload, value); - z_owned_bytes_t attachment; - z_bytes_encode_from_slice_map(&attachment, z_loan(attachment_map)); + z_owned_bytes_t attachment, key, val; + z_bytes_encode_from_string(&key, "hello"); + z_bytes_encode_from_string(&val, "there"); + z_bytes_encode_pair(&attachment, z_move(key), z_move(val)); z_put_options_t options; z_put_options_default(&options); @@ -71,6 +66,5 @@ int main(int argc, char **argv) { } z_close(z_move(s)); - z_drop(z_move(attachment_map)); return 0; } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index 3415842d1..ca72e6963 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -17,11 +17,18 @@ const char *kind_to_str(z_sample_kind_t kind); -bool attachment_map_reader(const z_loaned_slice_t* key, const z_loaned_slice_t* val, void *ctx) { - printf(" attachment: %.*s: '%.*s'\n", (int)z_slice_len(key), z_slice_data(key), - (int)z_slice_len(val), z_slice_data(val) +z_error_t attachment_reader(const z_loaned_bytes_t* key_value, void *context) { + z_owned_bytes_t k, v; + z_owned_str_t key, value; + z_bytes_decode_into_pair(key_value, &k, &v); + + z_bytes_decode_into_string(z_loan(k), &key); + z_bytes_decode_into_string(z_loan(v), &value); + + printf(" attachment: %.*s: '%.*s'\n", (int)z_str_len(z_loan(key)), z_str_data(z_loan(key)), + (int)z_str_len(z_loan(value)), z_str_data(z_loan(value)) ); - return false; + return 0; } void data_handler(const z_loaned_sample_t *sample, void *arg) { @@ -40,19 +47,7 @@ void data_handler(const z_loaned_sample_t *sample, void *arg) { // checks if attachment exists if (attachment != NULL) { // reads full attachment - z_owned_slice_map_t attachment_map; - z_bytes_decode_into_slice_map(attachment, &attachment_map); - - z_slice_map_iterate(z_loan(attachment_map), attachment_map_reader, NULL); - - // reads particular attachment item - z_view_slice_t attachment_key; - z_view_slice_from_str(&attachment_key, "index"); - const z_loaned_slice_t* index = z_slice_map_get(z_loan(attachment_map), z_loan(attachment_key)); - if (index != NULL) { - printf(" message number: %.*s\n", (int)z_slice_len(index), z_slice_data(index)); - } - z_drop(z_move(attachment_map)); + z_bytes_decode_into_iter(attachment, attachment_reader, NULL); } z_drop(z_move(payload_string)); } diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index e3d8e8b52..9cd0a632f 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1072,6 +1072,26 @@ ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *this_); * Constructs an owned shallow copy of data in provided uninitialized memory location. */ ZENOHC_API void z_bytes_clone(const struct z_loaned_bytes_t *this_, struct z_owned_bytes_t *dst); +/** + * Decodes payload into an iterator to `z_loaned_bytes_t`. + * @param this_: Data to decode. + * @param iterator_body: Iterator body function, that will be called on each data item. Returning non-zero value is treated as iteration loop `break`. + * @param context: Arbitrary context that will be passed to iterator_body. + * @return last value returned by iterator_body (or 0 if there are no elements in the payload). + */ +ZENOHC_API +z_error_t z_bytes_decode_into_iter(const struct z_loaned_bytes_t *this_, + z_error_t (*iterator_body)(const struct z_loaned_bytes_t *data, + void *context), + void *context); +/** + * Decodes into a pair of `z_owned_bytes` objects. + * @return 0 in case of success, negative error code otherwise. + */ +ZENOHC_API +z_error_t z_bytes_decode_into_pair(const struct z_loaned_bytes_t *this_, + struct z_owned_bytes_t *first, + struct z_owned_bytes_t *second); /** * Decodes data into an owned slice. * @@ -1104,6 +1124,17 @@ z_error_t z_bytes_decode_into_string(const struct z_loaned_bytes_t *this_, * created by `z_bytes_clone()`, they would still stay valid. */ ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); +/** + * Constructs payload from an iterator to `z_owned_bytes_t`. + * @param this_: An uninitialized location in memery for `z_owned_bytes_t` will be constructed. + * @param iterator_body: Iterator body function, providing data items. Returning NULL + * @param context: Arbitrary context that will be passed to iterator_body. + * @return 0 in case of success, negative error code otherwise. + */ +ZENOHC_API +z_error_t z_bytes_encode_from_iter(struct z_owned_bytes_t *this_, + void (*iterator_body)(struct z_owned_bytes_t *data, void *context), + void *context); /** * Encodes a slice by aliasing. */ @@ -1138,6 +1169,14 @@ ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const * Encodes a null-terminated string by copying. */ ZENOHC_API void z_bytes_encode_from_string_copy(struct z_owned_bytes_t *this_, const char *s); +/** + * Encodes a pair of `z_owned_bytes` objects which are consumed in the process. + * @return 0 in case of success, negative error code otherwise. + */ +ZENOHC_API +z_error_t z_bytes_encode_pair(struct z_owned_bytes_t *this_, + struct z_owned_bytes_t *first, + struct z_owned_bytes_t *second); /** * Returns total number of bytes in the payload. */ diff --git a/src/payload.rs b/src/payload.rs index d9f7231df..d5ad1116c 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,4 +1,4 @@ -use crate::errors::{self, z_error_t}; +use crate::errors::{self, z_error_t, Z_EINVAL, Z_EPARSE, Z_OK}; use crate::transmute::{ unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, @@ -10,8 +10,9 @@ use core::fmt; use std::any::Any; use std::io::{Read, Seek, SeekFrom}; use std::mem::MaybeUninit; +use std::os::raw::c_void; use std::slice::from_raw_parts_mut; -use zenoh::buffers::{ZSlice, ZSliceBuffer}; +use zenoh::buffers::{ZBuf, ZSlice, ZSliceBuffer}; use zenoh::bytes::{ZBytes, ZBytesReader}; pub use crate::opaque_types::z_owned_bytes_t; @@ -247,6 +248,119 @@ pub unsafe extern "C" fn z_bytes_encode_from_string_copy( z_bytes_encode_from_slice_copy(this, s as *const u8, libc::strlen(s)); } +/// Encodes a pair of `z_owned_bytes` objects which are consumed in the process. +/// @return 0 in case of success, negative error code otherwise. +#[no_mangle] +pub extern "C" fn z_bytes_encode_pair( + this: *mut MaybeUninit, + first: &mut z_owned_bytes_t, + second: &mut z_owned_bytes_t, +) -> z_error_t{ + let first = match first.transmute_mut().extract() { + Some(z) => z, + None => return Z_EINVAL, + }; + let second = match second.transmute_mut().extract() { + Some(z) => z, + None => return Z_EINVAL , + }; + let b = ZBytes::serialize((first, second)); + Inplace::init(this.transmute_uninit_ptr(), Some(b)); + return Z_OK; +} + +/// Decodes into a pair of `z_owned_bytes` objects. +/// @return 0 in case of success, negative error code otherwise. +#[no_mangle] +pub extern "C" fn z_bytes_decode_into_pair( + this: &z_loaned_bytes_t, + first: *mut MaybeUninit, + second: *mut MaybeUninit, +) -> z_error_t { + match this.transmute_ref().deserialize::<(ZBytes, ZBytes)>() { + Ok((a, b)) => { + Inplace::init(first.transmute_uninit_ptr(), Some(a)); + Inplace::init(second.transmute_uninit_ptr(), Some(b)); + return Z_OK; + }, + Err(e) => { + log::error!("Failed to decode the payload: {}", e); + return Z_EPARSE; + } + }; +} + +struct ZBytesInIterator { + body: extern "C" fn( + data: &mut MaybeUninit, + context: *mut c_void, + ), + context: *mut c_void, +} + +impl Iterator for ZBytesInIterator { + type Item = ZBuf; + + fn next(&mut self) -> Option { + let mut data = MaybeUninit::::uninit(); + + (self.body)(&mut data, self.context); + unsafe { data.assume_init().transmute_mut().extract() }.map(|b| b.into()) + } +} + + + +/// Constructs payload from an iterator to `z_owned_bytes_t`. +/// @param this_: An uninitialized location in memery for `z_owned_bytes_t` will be constructed. +/// @param iterator_body: Iterator body function, providing data items. Returning NULL +/// @param context: Arbitrary context that will be passed to iterator_body. +/// @return 0 in case of success, negative error code otherwise. +#[no_mangle] +pub extern "C" fn z_bytes_encode_from_iter( + this: *mut MaybeUninit, + iterator_body: extern "C" fn( + data: &mut MaybeUninit, + context: *mut c_void, + ), + context: *mut c_void, +) -> z_error_t { + let it = ZBytesInIterator { + body: iterator_body, + context, + }; + + let b = ZBytes::from_iter(it); + Inplace::init(this.transmute_uninit_ptr(), Some(b)); + return Z_OK; +} + +/// Decodes payload into an iterator to `z_loaned_bytes_t`. +/// @param this_: Data to decode. +/// @param iterator_body: Iterator body function, that will be called on each data item. Returning non-zero value is treated as iteration loop `break`. +/// @param context: Arbitrary context that will be passed to iterator_body. +/// @return last value returned by iterator_body (or 0 if there are no elements in the payload). +#[no_mangle] +pub extern "C" fn z_bytes_decode_into_iter( + this: &z_loaned_bytes_t, + iterator_body: extern "C" fn( + data: &z_loaned_bytes_t, + context: *mut c_void, + ) -> z_error_t, + context: *mut c_void, +) -> z_error_t { + let mut res = Z_OK; + for zb in this.transmute_ref().iter::() { + let b = ZBytes::new(zb); + res = iterator_body(b.transmute_handle(), context); + if res != Z_OK { + break; + } + } + + return res; +} + pub use crate::opaque_types::z_owned_bytes_reader_t; decl_transmute_owned!(Option>, z_owned_bytes_reader_t); pub use crate::opaque_types::z_loaned_bytes_reader_t; diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index 01b9115a2..d31eb4454 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -31,6 +31,59 @@ const char *const K_VAR = "k_var"; const char *const K_CONST = "k_const"; const char *const V_CONST = "v const"; +typedef struct attachement_context_t { + const char* keys[2]; + const char* values[2]; + size_t num_items; + size_t iteration_index; +} attachement_context_t; + +void create_attachement_it(z_owned_bytes_t* kv_pair, void* context) { + attachement_context_t *ctx = (attachement_context_t*)(context); + z_owned_bytes_t k, v; + if (ctx->iteration_index >= ctx->num_items) { + z_null(kv_pair); + return; + } else { + z_bytes_encode_from_string(&k, ctx->keys[ctx->iteration_index]); + z_bytes_encode_from_string(&v, ctx->values[ctx->iteration_index]); + } + + z_bytes_encode_pair(kv_pair, z_move(k), z_move(v)); + ctx->iteration_index++; +}; + +z_error_t check_attachement_it(const z_loaned_bytes_t* kv_pair, void* context) { + attachement_context_t *ctx = (attachement_context_t*)(context); + if (ctx->iteration_index >= ctx->num_items) { + perror("Attachment contains more items than expected\n"); + return -1; + } + + z_owned_bytes_t k, v; + z_owned_str_t k_str, v_str; + z_bytes_decode_into_pair(kv_pair, &k, &v); + + z_bytes_decode_into_string(z_loan(k), &k_str); + z_bytes_decode_into_string(z_loan(v), &v_str); + + if (strncmp(ctx->keys[ctx->iteration_index], z_str_data(z_loan(k_str)), z_str_len(z_loan(k_str))) != 0) { + perror("Incorrect attachment key\n"); + return -1; + } + if (strncmp(ctx->values[ctx->iteration_index], z_str_data(z_loan(v_str)), z_str_len(z_loan(v_str))) != 0) { + perror("Incorrect attachment value\n"); + return -1; + } + + z_drop(&k_str); + z_drop(&v_str); + z_drop(&k); + z_drop(&v); + ctx->iteration_index++; + return 0; +}; + int run_publisher() { SEM_WAIT(sem); @@ -50,26 +103,21 @@ int run_publisher() { return -1; } - z_owned_slice_map_t map; - z_slice_map_new(&map); - z_view_slice_t k_const, v_const; - z_view_slice_from_str(&k_const, K_CONST); - z_view_slice_from_str(&v_const, V_CONST); - z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_const), z_loan(v_const)); - z_publisher_put_options_t options; z_publisher_put_options_default(&options); for (int i = 0; i < values_count; ++i) { - z_view_slice_t k_var, v_var; - z_view_slice_from_str(&k_var, K_VAR); - z_view_slice_from_str(&v_var, values[i]); - z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_var), z_loan(v_var)); //value with the same key will be ovewritten + attachement_context_t out_attachment_context = (attachement_context_t){ + .keys = {K_CONST, K_VAR}, .values = {V_CONST, values[i]}, .num_items = 2, .iteration_index = 0 + }; z_owned_bytes_t attachment; - z_bytes_encode_from_slice_map(&attachment, z_loan(map)); + z_bytes_encode_from_iter(&attachment, create_attachement_it, (void*)&out_attachment_context); + options.attachment = &attachment; + z_view_slice_t v_var; + z_view_slice_from_str(&v_var, values[i]); z_owned_bytes_t payload; z_bytes_encode_from_slice(&payload, z_slice_data(z_loan(v_var)), z_slice_len(z_loan(v_var))); z_publisher_put(z_loan(pub), z_move(payload), &options); @@ -77,7 +125,6 @@ int run_publisher() { z_undeclare_publisher(z_move(pub)); z_close(z_move(s)); - z_drop(z_move(map)); return 0; } @@ -104,20 +151,15 @@ void data_handler(const z_loaned_sample_t *sample, void *arg) { exit(-1); } - z_owned_slice_map_t map; - z_bytes_decode_into_slice_map(attachment, &map); - - z_view_slice_t k_const, k_var; - z_view_slice_from_str(&k_const, K_CONST); - z_view_slice_from_str(&k_var, K_VAR); - - const z_loaned_slice_t* v_const = z_slice_map_get(z_loan(map), z_loan(k_const)); - ASSERT_STR_SLICE_EQUAL(V_CONST, v_const); - - const z_loaned_slice_t* v_var = z_slice_map_get(z_loan(map), z_loan(k_var)); - ASSERT_STR_SLICE_EQUAL(values[val_num], v_var); + attachement_context_t in_attachment_context = (attachement_context_t){ + .keys = {K_CONST, K_VAR}, .values = {V_CONST, values[val_num]}, .num_items = 2, .iteration_index = 0 + }; + z_error_t res = z_bytes_decode_into_iter(attachment, check_attachement_it, (void*)&in_attachment_context); + if (in_attachment_context.iteration_index != in_attachment_context.num_items || res != 0) { + perror("Failed to validate attachment"); + exit(-1); + } - z_drop(z_move(map)); if (++val_num == values_count) { exit(0); }; @@ -139,7 +181,7 @@ int run_subscriber() { z_owned_closure_sample_t callback; z_closure(&callback, data_handler, NULL, NULL); z_owned_subscriber_t sub; - ; + if (z_declare_subscriber(&sub, z_loan(s), z_loan(ke), z_move(callback), NULL) < 0) { perror("Unable to declare subscriber!"); return -1; diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index f468538dc..13384a632 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -29,6 +29,60 @@ const char *const K_VAR = "k_var"; const char *const K_CONST = "k_const"; const char *const V_CONST = "v const"; +typedef struct attachement_context_t { + const char* keys[2]; + const char* values[2]; + size_t num_items; + size_t iteration_index; +} attachement_context_t; + +void create_attachement_it(z_owned_bytes_t* kv_pair, void* context) { + attachement_context_t *ctx = (attachement_context_t*)(context); + z_owned_bytes_t k, v; + if (ctx->iteration_index >= ctx->num_items) { + z_null(kv_pair); + return; + } else { + z_bytes_encode_from_string(&k, ctx->keys[ctx->iteration_index]); + z_bytes_encode_from_string(&v, ctx->values[ctx->iteration_index]); + } + + z_bytes_encode_pair(kv_pair, z_move(k), z_move(v)); + ctx->iteration_index++; +}; + +z_error_t check_attachement_it(const z_loaned_bytes_t* kv_pair, void* context) { + attachement_context_t *ctx = (attachement_context_t*)(context); + if (ctx->iteration_index >= ctx->num_items) { + perror("Attachment contains more items than expected\n"); + return -1; + } + + z_owned_bytes_t k, v; + z_owned_str_t k_str, v_str; + z_bytes_decode_into_pair(kv_pair, &k, &v); + + z_bytes_decode_into_string(z_loan(k), &k_str); + z_bytes_decode_into_string(z_loan(v), &v_str); + + if (strncmp(ctx->keys[ctx->iteration_index], z_str_data(z_loan(k_str)), z_str_len(z_loan(k_str))) != 0) { + perror("Incorrect attachment key\n"); + return -1; + } + if (strncmp(ctx->values[ctx->iteration_index], z_str_data(z_loan(v_str)), z_str_len(z_loan(v_str))) != 0) { + perror("Incorrect attachment value\n"); + return -1; + } + + z_drop(&k_str); + z_drop(&v_str); + z_drop(&k); + z_drop(&v); + ctx->iteration_index++; + return 0; +}; + + void query_handler(const z_loaned_query_t *query, void *context) { static int value_num = 0; @@ -42,28 +96,24 @@ void query_handler(const z_loaned_query_t *query, void *context) { exit(-1); } - z_view_slice_t k_const, k_var; - z_view_slice_from_str(&k_const, K_CONST); - z_view_slice_from_str(&k_var, K_VAR); - - z_owned_slice_map_t map; - z_bytes_decode_into_slice_map(attachment, &map); - - const z_loaned_slice_t* v_const = z_slice_map_get(z_loan(map), z_loan(k_const)); - ASSERT_STR_SLICE_EQUAL(V_CONST, v_const); - - const z_loaned_slice_t* v_var = z_slice_map_get(z_loan(map), z_loan(k_var)); - ASSERT_STR_SLICE_EQUAL(values[value_num], v_var); - - z_owned_slice_map_t reply_map; - z_slice_map_new(&reply_map); - z_slice_map_insert_by_copy(z_loan_mut(reply_map), z_loan(k_const), v_const); + attachement_context_t in_attachment_context = (attachement_context_t){ + .keys = {K_CONST, K_VAR}, .values = {V_CONST, values[value_num]}, .num_items = 2, .iteration_index = 0 + }; + z_error_t res = z_bytes_decode_into_iter(attachment, check_attachement_it, (void*)&in_attachment_context); + if (in_attachment_context.iteration_index != in_attachment_context.num_items || res != 0) { + perror("Failed to validate attachment"); + exit(-1); + } z_query_reply_options_t options; z_query_reply_options_default(&options); - + z_owned_bytes_t reply_attachment; - z_bytes_encode_from_slice_map(&reply_attachment, z_loan(reply_map)); + attachement_context_t out_attachment_context = (attachement_context_t){ + .keys = {K_CONST}, .values = {V_CONST}, .num_items = 1, .iteration_index = 0 + }; + z_bytes_encode_from_iter(&reply_attachment, create_attachement_it, (void*)&out_attachment_context); + options.attachment = &reply_attachment; z_owned_bytes_t payload; @@ -72,7 +122,6 @@ void query_handler(const z_loaned_query_t *query, void *context) { z_view_keyexpr_t reply_ke; z_view_keyexpr_from_string(&reply_ke, (const char *)context); z_query_reply(query, z_loan(reply_ke), z_move(payload), &options); - z_drop(z_move(map)); if (++value_num == values_count) { exit(0); @@ -122,30 +171,21 @@ int run_get() { z_view_keyexpr_t ke; z_view_keyexpr_from_string(&ke, keyexpr); - z_owned_slice_map_t map; - z_slice_map_new(&map); - - z_view_slice_t k_const, k_var, v_const; - z_view_slice_from_str(&k_const, K_CONST); - z_view_slice_from_str(&k_var, K_VAR); - z_view_slice_from_str(&v_const, V_CONST); - - z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_const), z_loan(v_const)); - z_get_options_t opts; z_get_options_default(&opts); for (int val_num = 0; val_num < values_count; ++val_num) { - z_view_slice_t v_var; - z_view_slice_from_str(&v_var, values[val_num]); - z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_var), z_loan(v_var)); // will overwrite any previous value for the same key + attachement_context_t out_attachment_context = (attachement_context_t){ + .keys = {K_CONST, K_VAR}, .values = {V_CONST, values[val_num]}, .num_items = 2, .iteration_index = 0 + }; z_owned_reply_channel_t channel; zc_reply_fifo_new(&channel, 16); z_owned_bytes_t attachment; - z_bytes_encode_from_slice_map(&attachment, z_loan(map)); + z_bytes_encode_from_iter(&attachment, create_attachement_it, (void*)&out_attachment_context); + opts.attachment = &attachment; z_get(z_loan(s), z_loan(ke), "", z_move(channel.send), &opts); z_owned_reply_t reply; @@ -166,19 +206,21 @@ int run_get() { perror("Missing attachment!"); exit(-1); } - z_owned_slice_map_t received_map; - z_bytes_decode_into_slice_map(received_attachment, &received_map); - const z_loaned_slice_t* v_const_get = z_slice_map_get(z_loan(received_map), z_loan(k_const)); - ASSERT_STR_SLICE_EQUAL(V_CONST, v_const_get); + attachement_context_t in_attachment_context = (attachement_context_t){ + .keys = {K_CONST}, .values = {V_CONST}, .num_items = 1, .iteration_index = 0 + }; + z_error_t res = z_bytes_decode_into_iter(received_attachment, check_attachement_it, (void*)&in_attachment_context); + if (in_attachment_context.iteration_index != in_attachment_context.num_items || res != 0) { + perror("Failed to validate attachment"); + exit(-1); + } z_drop(z_move(payload_str)); - z_drop(z_move(received_map)); } z_drop(z_move(reply)); z_drop(z_move(channel)); } z_close(z_move(s)); - z_drop(z_move(map)); return 0; } From 94593d671e5f7b66f4ada82daf1d35dce48129fd Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 27 May 2024 17:49:40 +0200 Subject: [PATCH 2/4] z_bytes_encode_from_pair name change --- examples/z_pub_attachment.c | 2 +- examples/z_put.c | 2 +- include/zenoh_commons.h | 16 ++++++++-------- src/payload.rs | 2 +- tests/z_int_pub_sub_attachment_test.c | 2 +- tests/z_int_queryable_attachment_test.c | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index 8b4defa60..32ca37468 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -35,7 +35,7 @@ void create_attachment_iter(z_owned_bytes_t* kv_pair, void* context) { } else { z_bytes_encode_from_string(&k, kvs->data[kvs->current_idx].key); z_bytes_encode_from_string(&v, kvs->data[kvs->current_idx].value); - z_bytes_encode_pair(kv_pair, z_move(k), z_move(v)); + z_bytes_encode_from_pair(kv_pair, z_move(k), z_move(v)); kvs->current_idx++; } }; diff --git a/examples/z_put.c b/examples/z_put.c index c395c19b2..1b563caf2 100644 --- a/examples/z_put.c +++ b/examples/z_put.c @@ -54,7 +54,7 @@ int main(int argc, char **argv) { z_owned_bytes_t attachment, key, val; z_bytes_encode_from_string(&key, "hello"); z_bytes_encode_from_string(&val, "there"); - z_bytes_encode_pair(&attachment, z_move(key), z_move(val)); + z_bytes_encode_from_pair(&attachment, z_move(key), z_move(val)); z_put_options_t options; z_put_options_default(&options); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 9cd0a632f..14e8de991 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1135,6 +1135,14 @@ ZENOHC_API z_error_t z_bytes_encode_from_iter(struct z_owned_bytes_t *this_, void (*iterator_body)(struct z_owned_bytes_t *data, void *context), void *context); +/** + * Encodes a pair of `z_owned_bytes` objects which are consumed in the process. + * @return 0 in case of success, negative error code otherwise. + */ +ZENOHC_API +z_error_t z_bytes_encode_from_pair(struct z_owned_bytes_t *this_, + struct z_owned_bytes_t *first, + struct z_owned_bytes_t *second); /** * Encodes a slice by aliasing. */ @@ -1169,14 +1177,6 @@ ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const * Encodes a null-terminated string by copying. */ ZENOHC_API void z_bytes_encode_from_string_copy(struct z_owned_bytes_t *this_, const char *s); -/** - * Encodes a pair of `z_owned_bytes` objects which are consumed in the process. - * @return 0 in case of success, negative error code otherwise. - */ -ZENOHC_API -z_error_t z_bytes_encode_pair(struct z_owned_bytes_t *this_, - struct z_owned_bytes_t *first, - struct z_owned_bytes_t *second); /** * Returns total number of bytes in the payload. */ diff --git a/src/payload.rs b/src/payload.rs index d5ad1116c..8f427a007 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -251,7 +251,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_string_copy( /// Encodes a pair of `z_owned_bytes` objects which are consumed in the process. /// @return 0 in case of success, negative error code otherwise. #[no_mangle] -pub extern "C" fn z_bytes_encode_pair( +pub extern "C" fn z_bytes_encode_from_pair( this: *mut MaybeUninit, first: &mut z_owned_bytes_t, second: &mut z_owned_bytes_t, diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index d31eb4454..d57bf551f 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -49,7 +49,7 @@ void create_attachement_it(z_owned_bytes_t* kv_pair, void* context) { z_bytes_encode_from_string(&v, ctx->values[ctx->iteration_index]); } - z_bytes_encode_pair(kv_pair, z_move(k), z_move(v)); + z_bytes_encode_from_pair(kv_pair, z_move(k), z_move(v)); ctx->iteration_index++; }; diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 13384a632..61be13a03 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -47,7 +47,7 @@ void create_attachement_it(z_owned_bytes_t* kv_pair, void* context) { z_bytes_encode_from_string(&v, ctx->values[ctx->iteration_index]); } - z_bytes_encode_pair(kv_pair, z_move(k), z_move(v)); + z_bytes_encode_from_pair(kv_pair, z_move(k), z_move(v)); ctx->iteration_index++; }; From 9198c5705bea5ef37d9538e9e37f498c95e60ff2 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 27 May 2024 19:01:30 +0200 Subject: [PATCH 3/4] cargo.toml.in fix --- Cargo.toml.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml.in b/Cargo.toml.in index c7550a8d9..83414f3a9 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -56,7 +56,7 @@ const_format = "0.2.32" zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "dev/1.0.0", features = ["shared-memory", "unstable"], default-features = false } zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "dev/1.0.0", features = ["shared-memory"] } zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "dev/1.0.0" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "dev/1.0.0, features = ["unstable"] } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "dev/1.0.0", features = ["unstable"] } [build-dependencies] From 8bf9cd90cd941f09f6ec6d59d122e254d5d46d76 Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Tue, 28 May 2024 10:51:31 +0300 Subject: [PATCH 4/4] fix examples --- examples/z_get.c | 12 +++++------- examples/z_ping.c | 13 +++++++++---- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/examples/z_get.c b/examples/z_get.c index 8c4c45d23..8a4eb9c57 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -27,7 +27,7 @@ int main(int argc, char **argv) { expr = argv[1]; break; case 1: - // Do nothing + value = "Test Value"; break; } z_view_keyexpr_t keyexpr; @@ -49,7 +49,7 @@ int main(int argc, char **argv) { printf("Opening session...\n"); z_owned_session_t s; - if (!z_open(&s, z_move(config))) { + if (z_open(&s, z_move(config))) { printf("Unable to open session!\n"); exit(-1); } @@ -72,7 +72,7 @@ int main(int argc, char **argv) { for (z_call(z_loan(channel.recv), &reply); z_check(reply); z_call(z_loan(channel.recv), &reply)) { if (z_reply_is_ok(z_loan(reply))) { - const z_loaned_sample_t* sample = z_reply_ok(z_loan(reply)); + const z_loaned_sample_t *sample = z_reply_ok(z_loan(reply)); z_view_str_t key_str; z_keyexpr_to_string(z_sample_keyexpr(sample), &key_str); @@ -80,10 +80,8 @@ int main(int argc, char **argv) { z_owned_str_t reply_str; z_bytes_decode_into_string(z_sample_payload(sample), &reply_str); - printf(">> Received ('%.*s': '%.*s')\n", - (int)z_str_len(z_loan(key_str)), z_str_data(z_loan(key_str)), - (int)z_str_len(z_loan(reply_str)), z_str_data(z_loan(reply_str)) - ); + printf(">> Received ('%.*s': '%.*s')\n", (int)z_str_len(z_loan(key_str)), z_str_data(z_loan(key_str)), + (int)z_str_len(z_loan(reply_str)), z_str_data(z_loan(reply_str))); z_drop(z_move(reply_str)); } else { printf("Received an error\n"); diff --git a/examples/z_ping.c b/examples/z_ping.c index b98cec7f9..298cfed8f 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -11,7 +11,11 @@ #define PING_TIMEOUT_SEC 1 #define handle_error_en(en, msg) \ - do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) + do { \ + errno = en; \ + perror(msg); \ + exit(EXIT_FAILURE); \ + } while (0) z_owned_condvar_t cond; z_owned_mutex_t mutex; @@ -38,17 +42,17 @@ int main(int argc, char** argv) { -w (optional, int, default=%d): the warmup time in ms during which pings will be emitted but not measured\n\ -c (optional, string): the path to a configuration file for the session. If this option isn't passed, the default configuration will be used.\n\ ", - DEFAULT_PKT_SIZE, DEFAULT_PING_NB, DEFAULT_WARMUP_MS); + DEFAULT_PING_NB, DEFAULT_PKT_SIZE, DEFAULT_WARMUP_MS); return 1; } z_mutex_init(&mutex); z_condvar_init(&cond); - z_owned_config_t config; + z_owned_config_t config; if (args.config_path) { zc_config_from_file(&config, args.config_path); } else { z_config_default(&config); - } + } z_owned_session_t session; z_open(&session, z_move(config)); z_view_keyexpr_t ping; @@ -85,6 +89,7 @@ int main(int argc, char** argv) { } unsigned long* results = z_malloc(sizeof(unsigned long) * args.number_of_pings); for (int i = 0; i < args.number_of_pings; i++) { + z_bytes_encode_from_slice(&payload, data, args.size); z_clock_t measure_start = z_clock_now(); z_publisher_put(z_loan(pub), z_move(payload), NULL); int s = z_condvar_wait(z_loan(cond), z_loan_mut(mutex));