From 1c73e0c8aa5ba9a78f0309a9f5bb7fe5e9bfcb16 Mon Sep 17 00:00:00 2001 From: DenisBiryukov91 <155981813+DenisBiryukov91@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:21:03 +0200 Subject: [PATCH] serialization refactoring (#691) * serialization refactoring * Update examples/unix/c11/z_get_attachment.c Co-authored-by: Alexander Bushnev * renaming to ze_ * replace _into_ with _to_ * format * docs update * fix bytes slice iterator not to rely on serializer * removed from/to from ze_(de)serialize_ functions * make writer serializer owned and make them own z_bytes * docs fix * docs fix * test fix * remove ze_serializer_from_bytes; add ze_serializer_from/to_writer and ze_deserializer_from/to_reader; * remove ze_serializer_from_bytes; add ze_serializer_from/to_writer and ze_deserializer_from/to_reader; * add missing overloads for c++ functions * added z_bytes_reader_remaining and ze_deserializer_is_done methods * move serialization/deserialization under unstable * ci fix * fix serialization.h * report deserialization error when payload size is longer than deserialzie target * format * remove serialize/deserialize_sequence_end * fix missing return value --------- Co-authored-by: Alexander Bushnev --- .github/workflows/build-check.yaml | 2 +- docs/api.rst | 115 ++- docs/concepts.rst | 4 +- examples/arduino/z_get.ino | 2 +- examples/arduino/z_pub.ino | 2 +- examples/arduino/z_pull.ino | 2 +- examples/arduino/z_queryable.ino | 2 +- examples/arduino/z_sub.ino | 2 +- examples/espidf/z_get.c | 2 +- examples/espidf/z_pub.c | 2 +- examples/espidf/z_pull.c | 2 +- examples/espidf/z_queryable.c | 2 +- examples/espidf/z_sub.c | 2 +- examples/freertos_plus_tcp/z_get.c | 2 +- examples/freertos_plus_tcp/z_pub.c | 2 +- examples/freertos_plus_tcp/z_pub_st.c | 2 +- examples/freertos_plus_tcp/z_pull.c | 2 +- examples/freertos_plus_tcp/z_queryable.c | 2 +- examples/freertos_plus_tcp/z_sub.c | 2 +- examples/freertos_plus_tcp/z_sub_st.c | 2 +- examples/mbed/z_get.cpp | 2 +- examples/mbed/z_pub.cpp | 2 +- examples/mbed/z_pull.cpp | 2 +- examples/mbed/z_queryable.cpp | 2 +- examples/mbed/z_sub.cpp | 2 +- examples/unix/c11/z_bytes.c | 336 +++++---- examples/unix/c11/z_get.c | 4 +- examples/unix/c11/z_get_attachment.c | 117 ++- examples/unix/c11/z_get_channel.c | 2 +- examples/unix/c11/z_pub.c | 2 +- examples/unix/c11/z_pub_attachment.c | 46 +- examples/unix/c11/z_pub_st.c | 2 +- examples/unix/c11/z_pull.c | 2 +- examples/unix/c11/z_queryable.c | 2 +- examples/unix/c11/z_queryable_attachment.c | 128 ++-- examples/unix/c11/z_queryable_channel.c | 2 +- examples/unix/c11/z_sub.c | 2 +- examples/unix/c11/z_sub_attachment.c | 66 +- examples/unix/c11/z_sub_channel.c | 2 +- examples/unix/c11/z_sub_st.c | 2 +- examples/unix/c99/z_get.c | 2 +- examples/unix/c99/z_pub.c | 2 +- examples/unix/c99/z_pub_st.c | 2 +- examples/unix/c99/z_pull.c | 2 +- examples/unix/c99/z_queryable.c | 2 +- examples/unix/c99/z_sub.c | 2 +- examples/unix/c99/z_sub_st.c | 2 +- examples/windows/z_get.c | 2 +- examples/windows/z_pub_st.c | 2 +- examples/windows/z_pull.c | 2 +- examples/windows/z_queryable.c | 2 +- examples/windows/z_sub.c | 2 +- examples/windows/z_sub_st.c | 2 +- examples/zephyr/z_get.c | 2 +- examples/zephyr/z_pub.c | 2 +- examples/zephyr/z_pull.c | 2 +- examples/zephyr/z_queryable.c | 2 +- examples/zephyr/z_sub.c | 2 +- include/zenoh-pico/api/macros.h | 122 +++- include/zenoh-pico/api/olv_macros.h | 140 ++-- include/zenoh-pico/api/primitives.h | 455 ++---------- include/zenoh-pico/api/serialization.h | 809 +++++++++++++++++++++ include/zenoh-pico/api/types.h | 15 +- include/zenoh-pico/collections/bytes.h | 45 +- include/zenoh-pico/utils/endianness.h | 158 +++- include/zenoh-pico/utils/result.h | 1 + src/api/api.c | 194 +---- src/api/serialization.c | 169 +++++ src/collections/bytes.c | 215 ++---- src/utils/endianness.c | 134 ---- tests/z_api_alignment_test.c | 2 +- tests/z_api_bytes_test.c | 233 +++--- tests/z_bytes_test.c | 49 +- tests/z_channels_test.c | 34 +- tests/z_client_test.c | 6 +- tests/z_peer_multicast_test.c | 2 +- tests/z_perf_rx.c | 2 +- tests/z_test_fragment_rx.c | 2 +- zenohpico.pc | 2 +- 79 files changed, 2080 insertions(+), 1625 deletions(-) create mode 100644 include/zenoh-pico/api/serialization.h create mode 100644 src/api/serialization.c delete mode 100644 src/utils/endianness.c diff --git a/.github/workflows/build-check.yaml b/.github/workflows/build-check.yaml index 70a87854d..3f11c24c8 100644 --- a/.github/workflows/build-check.yaml +++ b/.github/workflows/build-check.yaml @@ -234,7 +234,7 @@ jobs: - name: Build project and run test run: | sudo apt install -y ninja-build - CMAKE_GENERATOR=Ninja make + Z_FEATURE_UNSTABLE_API=1 CMAKE_GENERATOR=Ninja make python3 ./build/tests/attachment.py timeout-minutes: 5 diff --git a/docs/api.rst b/docs/api.rst index c5f7864f8..ba9d3ef65 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -53,9 +53,8 @@ Data Structures .. autoctype:: types.h::zp_send_keep_alive_options_t .. 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 +.. autoctype:: serialization.h::ze_deserializer_t Owned Types @@ -71,6 +70,14 @@ See :ref:`owned_types_concept` Represents an array of bytes container. +.. c:type:: z_owned_bytes_writer_t + + Represents a payload writer. + +.. c:type:: ze_owned_serializer_t + + Represents a data serializer (unstable). + .. c:type:: z_owned_string_t Represents a string without null-terminator. @@ -140,6 +147,14 @@ See :ref:`loaned_types_concept` Represents an array of bytes container. +.. c:type:: z_loaned_bytes_writer_t + + Represents a payload writer. + +.. c:type:: ze_loaned_serializer_t + + Represents a data serializer (unstable). + .. c:type:: z_loaned_string_t Represents a string without null-terminator. @@ -320,54 +335,88 @@ Primitives .. autocfunction:: primitives.h::z_slice_len .. autocfunction:: primitives.h::z_slice_empty .. autocfunction:: primitives.h::z_slice_is_empty -.. autocfunction:: primitives.h::z_bytes_deserialize_into_int8 -.. autocfunction:: primitives.h::z_bytes_deserialize_into_int16 -.. autocfunction:: primitives.h::z_bytes_deserialize_into_int32 -.. autocfunction:: primitives.h::z_bytes_deserialize_into_int64 -.. autocfunction:: primitives.h::z_bytes_deserialize_into_uint8 -.. autocfunction:: primitives.h::z_bytes_deserialize_into_uint16 -.. autocfunction:: primitives.h::z_bytes_deserialize_into_uint32 -.. autocfunction:: primitives.h::z_bytes_deserialize_into_uint64 -.. autocfunction:: primitives.h::z_bytes_deserialize_into_float -.. autocfunction:: primitives.h::z_bytes_deserialize_into_double -.. autocfunction:: primitives.h::z_bytes_deserialize_into_slice -.. autocfunction:: primitives.h::z_bytes_deserialize_into_string -.. autocfunction:: primitives.h::z_bytes_serialize_from_int8 -.. autocfunction:: primitives.h::z_bytes_serialize_from_int16 -.. autocfunction:: primitives.h::z_bytes_serialize_from_int32 -.. autocfunction:: primitives.h::z_bytes_serialize_from_int64 -.. autocfunction:: primitives.h::z_bytes_serialize_from_uint8 -.. autocfunction:: primitives.h::z_bytes_serialize_from_uint16 -.. autocfunction:: primitives.h::z_bytes_serialize_from_uint32 -.. autocfunction:: primitives.h::z_bytes_serialize_from_uint64 -.. autocfunction:: primitives.h::z_bytes_serialize_from_float -.. autocfunction:: primitives.h::z_bytes_serialize_from_double +.. autocfunction:: serialization.h::ze_deserializer_from_bytes +.. autocfunction:: serialization.h::ze_deserializer_deserialize_int8 +.. autocfunction:: serialization.h::ze_deserializer_deserialize_int16 +.. autocfunction:: serialization.h::ze_deserializer_deserialize_int32 +.. autocfunction:: serialization.h::ze_deserializer_deserialize_int64 +.. autocfunction:: serialization.h::ze_deserializer_deserialize_uint8 +.. autocfunction:: serialization.h::ze_deserializer_deserialize_uint16 +.. autocfunction:: serialization.h::ze_deserializer_deserialize_uint32 +.. autocfunction:: serialization.h::ze_deserializer_deserialize_uint64 +.. autocfunction:: serialization.h::ze_deserializer_deserialize_float +.. autocfunction:: serialization.h::ze_deserializer_deserialize_double +.. autocfunction:: serialization.h::ze_deserializer_deserialize_slice +.. autocfunction:: serialization.h::ze_deserializer_deserialize_string +.. autocfunction:: serialization.h::ze_deserializer_deserialize_sequence_length +.. autocfunction:: serialization.h::ze_serializer_empty +.. autocfunction:: serialization.h::ze_serializer_finish +.. autocfunction:: serialization.h::ze_serializer_serialize_int8 +.. autocfunction:: serialization.h::ze_serializer_serialize_int16 +.. autocfunction:: serialization.h::ze_serializer_serialize_int32 +.. autocfunction:: serialization.h::ze_serializer_serialize_int64 +.. autocfunction:: serialization.h::ze_serializer_serialize_uint8 +.. autocfunction:: serialization.h::ze_serializer_serialize_uint16 +.. autocfunction:: serialization.h::ze_serializer_serialize_uint32 +.. autocfunction:: serialization.h::ze_serializer_serialize_uint64 +.. autocfunction:: serialization.h::ze_serializer_serialize_float +.. autocfunction:: serialization.h::ze_serializer_serialize_double +.. autocfunction:: serialization.h::ze_serializer_serialize_slice +.. autocfunction:: serialization.h::ze_serializer_serialize_buf +.. autocfunction:: serialization.h::ze_serializer_serialize_string +.. autocfunction:: serialization.h::ze_serializer_serialize_str +.. autocfunction:: serialization.h::ze_serializer_serialize_sequence_length +.. autocfunction:: serialization.h::ze_deserialize_int8 +.. autocfunction:: serialization.h::ze_deserialize_int16 +.. autocfunction:: serialization.h::ze_deserialize_int32 +.. autocfunction:: serialization.h::ze_deserialize_int64 +.. autocfunction:: serialization.h::ze_deserialize_uint8 +.. autocfunction:: serialization.h::ze_deserialize_uint16 +.. autocfunction:: serialization.h::ze_deserialize_uint32 +.. autocfunction:: serialization.h::ze_deserialize_uint64 +.. autocfunction:: serialization.h::ze_deserialize_float +.. autocfunction:: serialization.h::ze_deserialize_double +.. autocfunction:: serialization.h::ze_deserialize_slice +.. autocfunction:: serialization.h::ze_deserialize_string +.. autocfunction:: serialization.h::ze_deserializer_is_done +.. autocfunction:: serialization.h::ze_serialize_int8 +.. autocfunction:: serialization.h::ze_serialize_int16 +.. autocfunction:: serialization.h::ze_serialize_int32 +.. autocfunction:: serialization.h::ze_serialize_int64 +.. autocfunction:: serialization.h::ze_serialize_uint8 +.. autocfunction:: serialization.h::ze_serialize_uint16 +.. autocfunction:: serialization.h::ze_serialize_uint32 +.. autocfunction:: serialization.h::ze_serialize_uint64 +.. autocfunction:: serialization.h::ze_serialize_float +.. autocfunction:: serialization.h::ze_serialize_double +.. autocfunction:: serialization.h::ze_serialize_slice +.. autocfunction:: serialization.h::ze_serialize_buf +.. autocfunction:: serialization.h::ze_serialize_string +.. autocfunction:: serialization.h::ze_serialize_str .. autocfunction:: primitives.h::z_bytes_from_slice -.. autocfunction:: primitives.h::z_bytes_serialize_from_slice +.. autocfunction:: primitives.h::z_bytes_copy_from_slice .. autocfunction:: primitives.h::z_bytes_from_buf -.. autocfunction:: primitives.h::z_bytes_serialize_from_buf +.. autocfunction:: primitives.h::z_bytes_copy_from_buf .. autocfunction:: primitives.h::z_bytes_from_static_buf .. autocfunction:: primitives.h::z_bytes_from_string -.. autocfunction:: primitives.h::z_bytes_serialize_from_string +.. autocfunction:: primitives.h::z_bytes_copy_from_string .. autocfunction:: primitives.h::z_bytes_from_str -.. autocfunction:: primitives.h::z_bytes_serialize_from_str +.. autocfunction:: primitives.h::z_bytes_copy_from_str .. autocfunction:: primitives.h::z_bytes_from_static_str .. autocfunction:: primitives.h::z_bytes_empty .. autocfunction:: primitives.h::z_bytes_len .. 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 .. autocfunction:: primitives.h::z_bytes_reader_seek .. autocfunction:: primitives.h::z_bytes_reader_tell -.. autocfunction:: primitives.h::z_bytes_get_writer +.. autocfunction:: primitives.h::z_bytes_reader_remaining +.. autocfunction:: primitives.h::z_bytes_writer_empty +.. autocfunction:: primitives.h::z_bytes_writer_finish .. autocfunction:: primitives.h::z_bytes_writer_write_all .. autocfunction:: primitives.h::z_bytes_writer_append -.. autocfunction:: primitives.h::z_bytes_writer_append_bounded .. autocfunction:: primitives.h::z_timestamp_check .. autocfunction:: primitives.h::z_query_target_default .. autocfunction:: primitives.h::z_query_consolidation_auto diff --git a/docs/concepts.rst b/docs/concepts.rst index 189f06c4c..3458539f2 100644 --- a/docs/concepts.rst +++ b/docs/concepts.rst @@ -133,11 +133,11 @@ affect the owned object. However, passing the structure to a function transfers z_publisher_put_options_default(&options); int64_t metadata = 42; z_owned_bytes_t attachment; - z_bytes_serialize_from_int64(&attachment, metadata); + ze_serialize_int64(&attachment, metadata); options.attachment = z_move(attachment); // the data itself is still in the `attachment` z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, "Don't panic!"); + z_bytes_copy_from_str(&payload, "Don't panic!"); z_publisher_put(z_loan(pub), z_move(payload), &options); // the `payload` and `attachment` are consumed by the `z_publisher_put` function diff --git a/examples/arduino/z_get.ino b/examples/arduino/z_get.ino index bb4658a31..d67b5c8f9 100644 --- a/examples/arduino/z_get.ino +++ b/examples/arduino/z_get.ino @@ -45,7 +45,7 @@ void reply_handler(z_loaned_reply_t *oreply, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t replystr; - z_bytes_deserialize_into_string(z_sample_payload(sample), &replystr); + z_bytes_to_string(z_sample_payload(sample), &replystr); Serial.print(" >> [Get listener] Received ("); Serial.write(z_string_data(z_view_string_loan(&keystr)), z_string_len(z_view_string_loan(&keystr))); diff --git a/examples/arduino/z_pub.ino b/examples/arduino/z_pub.ino index 6cadb2d07..491a20bc1 100644 --- a/examples/arduino/z_pub.ino +++ b/examples/arduino/z_pub.ino @@ -109,7 +109,7 @@ void loop() { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); if (z_publisher_put(z_publisher_loan(&pub), z_bytes_move(&payload), NULL) < 0) { Serial.println("Error while publishing data"); diff --git a/examples/arduino/z_pull.ino b/examples/arduino/z_pull.ino index d9cde25d5..cb6b14705 100644 --- a/examples/arduino/z_pull.ino +++ b/examples/arduino/z_pull.ino @@ -104,7 +104,7 @@ void loop() { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(z_sample_loan(&sample)), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(z_sample_loan(&sample)), &value); + z_bytes_to_string(z_sample_payload(z_sample_loan(&sample)), &value); Serial.print(">> [Subscriber] Pulled ("); Serial.write(z_string_data(z_view_string_loan(&keystr)), z_string_len(z_view_string_loan(&keystr))); Serial.print(": "); diff --git a/examples/arduino/z_queryable.ino b/examples/arduino/z_queryable.ino index 8f37c68ab..1e3026e47 100644 --- a/examples/arduino/z_queryable.ino +++ b/examples/arduino/z_queryable.ino @@ -43,7 +43,7 @@ void query_handler(z_loaned_query_t *query, void *arg) { // Process value z_owned_string_t payload_string; - z_bytes_deserialize_into_string(z_query_payload(query), &payload_string); + z_bytes_to_string(z_query_payload(query), &payload_string); if (z_string_len(z_string_loan(&payload_string)) > 1) { Serial.print(" with value '"); Serial.write(z_string_data(z_string_loan(&payload_string)), z_string_len(z_string_loan(&payload_string))); diff --git a/examples/arduino/z_sub.ino b/examples/arduino/z_sub.ino index fa612fbf5..883f6e442 100644 --- a/examples/arduino/z_sub.ino +++ b/examples/arduino/z_sub.ino @@ -37,7 +37,7 @@ void data_handler(z_loaned_sample_t *sample, void *arg) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); Serial.print(" >> [Subscription listener] Received ("); Serial.write(z_string_data(z_view_string_loan(&keystr)), z_string_len(z_view_string_loan(&keystr))); diff --git a/examples/espidf/z_get.c b/examples/espidf/z_get.c index 090284579..3ac46a3ea 100644 --- a/examples/espidf/z_get.c +++ b/examples/espidf/z_get.c @@ -109,7 +109,7 @@ void reply_handler(z_loaned_reply_t *oreply, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t replystr; - z_bytes_deserialize_into_string(z_sample_payload(sample), &replystr); + z_bytes_to_string(z_sample_payload(sample), &replystr); printf(" >> Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(replystr)), z_string_data(z_loan(replystr))); diff --git a/examples/espidf/z_pub.c b/examples/espidf/z_pub.c index 88cb419cd..a4d3de494 100644 --- a/examples/espidf/z_pub.c +++ b/examples/espidf/z_pub.c @@ -157,7 +157,7 @@ void app_main() { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); z_publisher_put(z_loan(pub), z_move(payload), NULL); } diff --git a/examples/espidf/z_pull.c b/examples/espidf/z_pull.c index ba07d4b5a..f79fe348b 100644 --- a/examples/espidf/z_pull.c +++ b/examples/espidf/z_pull.c @@ -164,7 +164,7 @@ void app_main() { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(z_loan(sample)), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(z_loan(sample)), &value); + z_bytes_to_string(z_sample_payload(z_loan(sample)), &value); printf(">> [Subscriber] Pulled ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/espidf/z_queryable.c b/examples/espidf/z_queryable.c index 3aeed6cb6..a0798410d 100644 --- a/examples/espidf/z_queryable.c +++ b/examples/espidf/z_queryable.c @@ -111,7 +111,7 @@ void query_handler(z_loaned_query_t *query, void *ctx) { z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(params)), z_string_data(z_loan(params))); // Process value z_owned_string_t payload_string; - z_bytes_deserialize_into_string(z_query_payload(query), &payload_string); + z_bytes_to_string(z_query_payload(query), &payload_string); if (z_string_len(z_loan(payload_string)) > 0) { printf(" with value '%.*s'\n", (int)z_string_len(z_loan(payload_string)), z_string_data(z_loan(payload_string))); diff --git a/examples/espidf/z_sub.c b/examples/espidf/z_sub.c index 3d4653f9b..dff138c37 100644 --- a/examples/espidf/z_sub.c +++ b/examples/espidf/z_sub.c @@ -104,7 +104,7 @@ void data_handler(z_loaned_sample_t* sample, void* arg) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(" >> [Subscriber handler] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_view_string_loan(&keystr)), z_string_data(z_view_string_loan(&keystr)), (int)z_string_len(z_string_loan(&value)), z_string_data(z_string_loan(&value))); diff --git a/examples/freertos_plus_tcp/z_get.c b/examples/freertos_plus_tcp/z_get.c index c71c5b48a..aa679bf79 100644 --- a/examples/freertos_plus_tcp/z_get.c +++ b/examples/freertos_plus_tcp/z_get.c @@ -43,7 +43,7 @@ void reply_handler(z_loaned_reply_t *reply, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t replystr; - z_bytes_deserialize_into_string(z_sample_payload(sample), &replystr); + z_bytes_to_string(z_sample_payload(sample), &replystr); printf(">> Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(replystr)), z_string_data(z_loan(replystr))); diff --git a/examples/freertos_plus_tcp/z_pub.c b/examples/freertos_plus_tcp/z_pub.c index 36c006bed..c7db2eb7b 100644 --- a/examples/freertos_plus_tcp/z_pub.c +++ b/examples/freertos_plus_tcp/z_pub.c @@ -99,7 +99,7 @@ void app_main(void) { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); z_publisher_put_options_t options; z_publisher_put_options_default(&options); diff --git a/examples/freertos_plus_tcp/z_pub_st.c b/examples/freertos_plus_tcp/z_pub_st.c index 21d6b33ec..f0532ac31 100644 --- a/examples/freertos_plus_tcp/z_pub_st.c +++ b/examples/freertos_plus_tcp/z_pub_st.c @@ -65,7 +65,7 @@ void app_main(void) { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); z_publisher_put(z_loan(pub), z_move(payload), NULL); ++idx; diff --git a/examples/freertos_plus_tcp/z_pull.c b/examples/freertos_plus_tcp/z_pull.c index dfca1d6df..065c31707 100644 --- a/examples/freertos_plus_tcp/z_pull.c +++ b/examples/freertos_plus_tcp/z_pull.c @@ -73,7 +73,7 @@ void app_main(void) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(z_loan(sample)), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(z_loan(sample)), &value); + z_bytes_to_string(z_sample_payload(z_loan(sample)), &value); printf(">> [Subscriber] Pulled ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/freertos_plus_tcp/z_queryable.c b/examples/freertos_plus_tcp/z_queryable.c index 4504e46e1..009c48c6b 100644 --- a/examples/freertos_plus_tcp/z_queryable.c +++ b/examples/freertos_plus_tcp/z_queryable.c @@ -39,7 +39,7 @@ void query_handler(z_loaned_query_t *query, void *ctx) { z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(params)), z_string_data(z_loan(params))); // Process value z_owned_string_t payload_string; - z_bytes_deserialize_into_string(z_query_payload(query), &payload_string); + z_bytes_to_string(z_query_payload(query), &payload_string); if (z_string_len(z_loan(payload_string)) > 0) { printf(" with value '%.*s'\n", (int)z_string_len(z_loan(payload_string)), z_string_data(z_loan(payload_string))); diff --git a/examples/freertos_plus_tcp/z_sub.c b/examples/freertos_plus_tcp/z_sub.c index 9f8f1610a..93de97928 100644 --- a/examples/freertos_plus_tcp/z_sub.c +++ b/examples/freertos_plus_tcp/z_sub.c @@ -33,7 +33,7 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(">> [Subscriber] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/freertos_plus_tcp/z_sub_st.c b/examples/freertos_plus_tcp/z_sub_st.c index 7d3468216..71a6e063c 100644 --- a/examples/freertos_plus_tcp/z_sub_st.c +++ b/examples/freertos_plus_tcp/z_sub_st.c @@ -36,7 +36,7 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(">> [Subscriber] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/mbed/z_get.cpp b/examples/mbed/z_get.cpp index 7939e1bce..0747cb158 100644 --- a/examples/mbed/z_get.cpp +++ b/examples/mbed/z_get.cpp @@ -39,7 +39,7 @@ void reply_handler(z_loaned_reply_t *oreply, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t replystr; - z_bytes_deserialize_into_string(z_sample_payload(sample), &replystr); + z_bytes_to_string(z_sample_payload(sample), &replystr); printf(" >> Received ('%.*s': '%.*s')\n", (int)z_string_len(z_view_string_loan(&keystr)), z_string_data(z_view_string_loan(&keystr)), (int)z_string_len(z_string_loan(&replystr)), diff --git a/examples/mbed/z_pub.cpp b/examples/mbed/z_pub.cpp index c3515eb28..9079b0bd6 100644 --- a/examples/mbed/z_pub.cpp +++ b/examples/mbed/z_pub.cpp @@ -77,7 +77,7 @@ int main(int argc, char **argv) { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); z_publisher_put(z_publisher_loan(&pub), z_bytes_move(&payload), NULL); } diff --git a/examples/mbed/z_pull.cpp b/examples/mbed/z_pull.cpp index 39b30b61b..7c92bbc62 100644 --- a/examples/mbed/z_pull.cpp +++ b/examples/mbed/z_pull.cpp @@ -86,7 +86,7 @@ int main(int argc, char **argv) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(z_sample_loan(&sample)), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(z_sample_loan(&sample)), &value); + z_bytes_to_string(z_sample_payload(z_sample_loan(&sample)), &value); printf(">> [Subscriber] Pulled ('%.*s': '%.*s')\n", (int)z_string_len(z_view_string_loan(&keystr)), z_string_data(z_view_string_loan(&keystr)), (int)z_string_len(z_string_loan(&value)), z_string_data(z_string_loan(&value))); diff --git a/examples/mbed/z_queryable.cpp b/examples/mbed/z_queryable.cpp index 0732c5033..a33690057 100644 --- a/examples/mbed/z_queryable.cpp +++ b/examples/mbed/z_queryable.cpp @@ -42,7 +42,7 @@ void query_handler(z_loaned_query_t *query, void *ctx) { z_string_data(z_view_string_loan(¶ms))); // Process value z_owned_string_t payload_string; - z_bytes_deserialize_into_string(z_query_payload(query), &payload_string); + z_bytes_to_string(z_query_payload(query), &payload_string); if (z_string_len(z_string_loan(&payload_string)) > 1) { printf(" with value '%.*s'\n", (int)z_string_len(z_string_loan(&payload_string)), z_string_data(z_string_loan(&payload_string))); diff --git a/examples/mbed/z_sub.cpp b/examples/mbed/z_sub.cpp index 6f8576cf4..77184652b 100644 --- a/examples/mbed/z_sub.cpp +++ b/examples/mbed/z_sub.cpp @@ -34,7 +34,7 @@ void data_handler(z_loaned_sample_t *sample, void *arg) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(" >> [Subscriber handler] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_view_string_loan(&keystr)), z_string_data(z_view_string_loan(&keystr)), (int)z_string_len(z_string_loan(&value)), z_string_data(z_string_loan(&value))); diff --git a/examples/unix/c11/z_bytes.c b/examples/unix/c11/z_bytes.c index a5a074b02..cef3b2113 100644 --- a/examples/unix/c11/z_bytes.c +++ b/examples/unix/c11/z_bytes.c @@ -23,179 +23,201 @@ #undef NDEBUG #include -#include "zenoh-pico/system/platform.h" +typedef struct custom_struct_t { + float f; + uint64_t u[2][3]; + const char *c; +} custom_struct_t; typedef struct kv_pair_t { - const char *key; - const char *value; + int32_t key; + z_owned_string_t value; } kv_pair_t; -typedef struct kv_pairs_tx_t { - const kv_pair_t *data; - uint32_t len; - uint32_t current_idx; -} kv_pairs_tx_t; - -typedef struct kv_pair_decoded_t { - z_owned_string_t key; - z_owned_string_t value; -} kv_pair_decoded_t; - -typedef struct kv_pairs_rx_t { - kv_pair_decoded_t *data; - uint32_t len; - uint32_t current_idx; -} kv_pairs_rx_t; - -static bool hashmap_iter(z_owned_bytes_t *kv_pair, void *context); -static bool iter_body(z_owned_bytes_t *b, void *context); -static void parse_hashmap(kv_pairs_rx_t *kvp, const z_loaned_bytes_t *hashmap); -static void drop_hashmap(kv_pairs_rx_t *kvp); static void print_slice_data(z_view_slice_t *slice); int main(void) { - // z_owned_encoding_t encoding; + // Wrapping raw data into z_bytes_t z_owned_bytes_t payload; - - // Number types: uint8, uint16, uint32, uint64, int8, int16, int32, int64, float, double - uint32_t input_u32 = 123456; - uint32_t output_u32 = 0; - z_bytes_serialize_from_uint32(&payload, input_u32); - z_bytes_deserialize_into_uint32(z_loan(payload), &output_u32); - assert(input_u32 == output_u32); - z_drop(z_move(payload)); - // Corresponding encoding to be used in operations options like `z_put()`, `z_get()`, etc. - // encoding = ZP_ENCODING_ZENOH_UINT32; - - // String, also work with and z_owned_string_t - const char *input_str = "test"; - z_owned_string_t output_string; - z_bytes_serialize_from_str(&payload, input_str); - z_bytes_deserialize_into_string(z_loan(payload), &output_string); - assert(strncmp(input_str, z_string_data(z_loan(output_string)), strlen(input_str)) == 0); - z_drop(z_move(payload)); - z_drop(z_move(output_string)); - // Corresponding encoding to be used in operations options like `z_put()`, `z_get()`, etc. - // encoding = ZP_ENCODING_ZENOH_STRING; - - // Bytes, also work with z_owned_slice_t - const uint8_t input_bytes[] = {1, 2, 3, 4}; - z_owned_slice_t output_bytes; - z_bytes_serialize_from_buf(&payload, input_bytes, sizeof(input_bytes)); - z_bytes_deserialize_into_slice(z_loan(payload), &output_bytes); - assert(memcmp(input_bytes, z_slice_data(z_loan(output_bytes)), sizeof(input_bytes)) == 0); - z_drop(z_move(payload)); - z_drop(z_move(output_bytes)); - // Corresponding encoding to be used in operations options like `z_put()`, `z_get()`, etc. - // encoding = ZP_ENCODING_ZENOH_BYTES; // That's the default value - - // Writer reader - uint8_t input_writer[] = {0, 1, 2, 3, 4}; - uint8_t output_reader[5] = {0}; - z_bytes_empty(&payload); - z_bytes_writer_t writer = z_bytes_get_writer(z_bytes_loan_mut(&payload)); - z_bytes_writer_write_all(&writer, input_writer, 3); - z_bytes_writer_write_all(&writer, input_writer + 3, 2); - z_bytes_reader_t reader = z_bytes_get_reader(z_bytes_loan(&payload)); - z_bytes_reader_read(&reader, output_reader, sizeof(output_reader)); - assert(0 == memcmp(input_writer, output_reader, sizeof(output_reader))); - z_drop(z_move(payload)); - - // Bytes iterator - uint8_t result_iter[] = {0, 1, 2, 3, 4}; - uint8_t output_iter[5] = {0}; - uint8_t context = 0; - z_bytes_from_iter(&payload, iter_body, (void *)(&context)); - z_bytes_iterator_t it = z_bytes_get_iterator(z_bytes_loan(&payload)); - - z_owned_bytes_t current_item; - size_t i = 0; - while (z_bytes_iterator_next(&it, ¤t_item)) { - z_bytes_deserialize_into_uint8(z_bytes_loan(¤t_item), &output_reader[i]); - z_bytes_drop(z_bytes_move(¤t_item)); - i++; + { + const uint8_t input_bytes[] = {1, 2, 3, 4}; + z_owned_slice_t output_bytes; + z_bytes_copy_from_buf(&payload, input_bytes, sizeof(input_bytes)); + z_bytes_to_slice(z_loan(payload), &output_bytes); + assert(memcmp(input_bytes, z_slice_data(z_loan(output_bytes)), z_slice_len(z_loan(output_bytes))) == 0); + z_drop(z_move(payload)); + z_drop(z_move(output_bytes)); + + // The same can be done for const char* + const char *input_str = "test"; + z_owned_string_t output_string; + z_bytes_copy_from_str(&payload, input_str); + z_bytes_to_string(z_loan(payload), &output_string); + assert(strncmp(input_str, z_string_data(z_loan(output_string)), z_string_len(z_loan(output_string))) == 0); + z_drop(z_move(payload)); + z_drop(z_move(output_string)); } - assert(memcmp(output_iter, result_iter, sizeof(output_iter))); - z_drop(z_move(payload)); - - // Hash map - kv_pair_t input_hashmap[1]; - input_hashmap[0] = (kv_pair_t){.key = "test_key", .value = "test_value"}; - kv_pairs_tx_t ctx = (kv_pairs_tx_t){.data = input_hashmap, .current_idx = 0, .len = 1}; - z_bytes_from_iter(&payload, hashmap_iter, (void *)&ctx); - kv_pairs_rx_t output_hashmap = { - .current_idx = 0, .len = 16, .data = (kv_pair_decoded_t *)malloc(16 * sizeof(kv_pair_decoded_t))}; - parse_hashmap(&output_hashmap, z_loan(payload)); - assert(strncmp(input_hashmap[0].key, _z_string_data(z_loan(output_hashmap.data[0].key)), - strlen(input_hashmap[0].key)) == 0); - assert(strncmp(input_hashmap[0].value, _z_string_data(z_loan(output_hashmap.data[0].value)), - strlen(input_hashmap[0].value)) == 0); - z_drop(z_move(payload)); - drop_hashmap(&output_hashmap); - - // Slice iterator - kv_pair_t input_val[1]; - input_val[0] = (kv_pair_t){.key = "test_key", .value = "test_value"}; - ctx = (kv_pairs_tx_t){.data = input_val, .current_idx = 0, .len = 1}; - z_bytes_from_iter(&payload, hashmap_iter, (void *)&ctx); - z_bytes_slice_iterator_t slice_iter = z_bytes_get_slice_iterator(z_bytes_loan(&payload)); - z_view_slice_t curr_slice; - while (z_bytes_slice_iterator_next(&slice_iter, &curr_slice)) { - printf("slice len: %d, slice data: '", (int)z_slice_len(z_view_slice_loan(&curr_slice))); - print_slice_data(&curr_slice); - printf("'\n"); +#if defined(Z_FEATURE_UNSTABLE_API) + // Serialization + { + // Arithmetic types: uint8, uint16, uint32, uint64, int8, int16, int32, int64, float, double + uint32_t input_u32 = 1234; + uint32_t output_u32 = 0; + ze_serialize_uint32(&payload, input_u32); + ze_deserialize_uint32(z_loan(payload), &output_u32); + assert(input_u32 == output_u32); + z_drop(z_move(payload)); + // Corresponding encoding to be used in operations options like `z_put()`, `z_get()`, etc. + // const z_loaned_encoding* encoding = z_encoding_zenoh_uint32(); } - z_drop(z_move(payload)); - - return 0; -} - -static bool iter_body(z_owned_bytes_t *b, void *context) { - uint8_t *val = (uint8_t *)context; - if (*val >= 5) { - return false; - } else { - z_bytes_serialize_from_uint8(b, *val); +#endif + // Writer/reader for raw bytes + { + uint8_t input_writer[] = {0, 1, 2, 3, 4}; + uint8_t output_reader[5] = {0}; + + z_owned_bytes_writer_t writer; + z_bytes_writer_empty(&writer); + z_bytes_writer_write_all(z_loan_mut(writer), input_writer, 3); + z_bytes_writer_write_all(z_loan_mut(writer), input_writer + 3, 2); + z_bytes_writer_finish(z_move(writer), &payload); + z_bytes_reader_t reader = z_bytes_get_reader(z_loan(payload)); + z_bytes_reader_read(&reader, output_reader, sizeof(output_reader)); + assert(0 == memcmp(input_writer, output_reader, sizeof(output_reader))); + z_drop(z_move(payload)); } - *val = *val + 1; - return true; -} - -static bool hashmap_iter(z_owned_bytes_t *kv_pair, void *context) { - kv_pairs_tx_t *kvs = (kv_pairs_tx_t *)(context); - z_owned_bytes_t k, v; - if (kvs->current_idx >= kvs->len) { - return false; - } else { - z_bytes_serialize_from_str(&k, kvs->data[kvs->current_idx].key); - z_bytes_serialize_from_str(&v, kvs->data[kvs->current_idx].value); - z_bytes_from_pair(kv_pair, z_move(k), z_move(v)); - kvs->current_idx++; - return true; +#if defined(Z_FEATURE_UNSTABLE_API) + // Using serializer/deserializer for composite types + { + // A sequence of primitive types + int32_t input_vec[] = {1, 2, 3, 4}; + int32_t output_vec[4] = {0}; + ze_owned_serializer_t serializer; + ze_serializer_empty(&serializer); + ze_serializer_serialize_sequence_length(z_loan_mut(serializer), 4); + for (size_t i = 0; i < 4; ++i) { + ze_serializer_serialize_int32(z_loan_mut(serializer), input_vec[i]); + } + ze_serializer_finish(z_move(serializer), &payload); + + ze_deserializer_t deserializer = ze_deserializer_from_bytes(z_loan(payload)); + size_t num_elements = 0; + ze_deserializer_deserialize_sequence_length(&deserializer, &num_elements); + assert(num_elements == 4); + for (size_t i = 0; i < num_elements; ++i) { + ze_deserializer_deserialize_int32(&deserializer, &output_vec[i]); + } + + for (size_t i = 0; i < 4; ++i) { + assert(input_vec[i] == output_vec[i]); + } + z_drop(z_move(payload)); } -} -static void parse_hashmap(kv_pairs_rx_t *kvp, const z_loaned_bytes_t *hashmap) { - z_owned_bytes_t kv, first, second; - z_bytes_iterator_t iter = z_bytes_get_iterator(hashmap); - - while (kvp->current_idx < kvp->len && z_bytes_iterator_next(&iter, &kv)) { - z_bytes_deserialize_into_pair(z_loan(kv), &first, &second); - z_bytes_deserialize_into_string(z_loan(first), &kvp->data[kvp->current_idx].key); - z_bytes_deserialize_into_string(z_loan(second), &kvp->data[kvp->current_idx].value); - z_bytes_drop(z_bytes_move(&first)); - z_bytes_drop(z_bytes_move(&second)); - z_bytes_drop(z_bytes_move(&kv)); - kvp->current_idx++; + { + // Sequence of key-value pairs + kv_pair_t kvs_input[2]; + kvs_input[0].key = 0; + z_string_from_str(&kvs_input[0].value, "abc", NULL, NULL); + kvs_input[1].key = 1; + z_string_from_str(&kvs_input[1].value, "def", NULL, NULL); + + ze_owned_serializer_t serializer; + ze_serializer_empty(&serializer); + ze_serializer_serialize_sequence_length(z_loan_mut(serializer), 2); + for (size_t i = 0; i < 2; ++i) { + ze_serializer_serialize_int32(z_loan_mut(serializer), kvs_input[i].key); + ze_serializer_serialize_string(z_loan_mut(serializer), z_loan(kvs_input[i].value)); + } + ze_serializer_finish(z_move(serializer), &payload); + + ze_deserializer_t deserializer = ze_deserializer_from_bytes(z_loan(payload)); + size_t num_elements = 0; + ze_deserializer_deserialize_sequence_length(&deserializer, &num_elements); + assert(num_elements == 2); + kv_pair_t kvs_output[2]; + for (size_t i = 0; i < num_elements; ++i) { + ze_deserializer_deserialize_int32(&deserializer, &kvs_output[i].key); + ze_deserializer_deserialize_string(&deserializer, &kvs_output[i].value); + } + + for (size_t i = 0; i < 2; ++i) { + assert(kvs_input[i].key == kvs_output[i].key); + assert(strncmp(z_string_data(z_loan(kvs_input[i].value)), z_string_data(z_loan(kvs_output[i].value)), + z_string_len(z_loan(kvs_input[i].value))) == 0); + z_drop(z_move(kvs_input[i].value)); + z_drop(z_move(kvs_output[i].value)); + } + z_drop(z_move(payload)); } -} -static void drop_hashmap(kv_pairs_rx_t *kvp) { - for (size_t i = 0; i < kvp->current_idx; i++) { - z_string_drop(z_string_move(&kvp->data[i].key)); - z_string_drop(z_string_move(&kvp->data[i].value)); + { + // Custom struct/tuple serializaiton + custom_struct_t cs = (custom_struct_t){.f = 1.0f, .u = {{1, 2, 3}, {4, 5, 6}}, .c = "test"}; + + ze_owned_serializer_t serializer; + ze_serializer_empty(&serializer); + ze_serializer_serialize_float(z_loan_mut(serializer), cs.f); + ze_serializer_serialize_sequence_length(z_loan_mut(serializer), 2); + for (size_t i = 0; i < 2; ++i) { + ze_serializer_serialize_sequence_length(z_loan_mut(serializer), 3); + for (size_t j = 0; j < 3; ++j) { + ze_serializer_serialize_uint64(z_loan_mut(serializer), cs.u[i][j]); + } + } + ze_serializer_serialize_str(z_loan_mut(serializer), cs.c); + ze_serializer_finish(z_move(serializer), &payload); + + float f = 0.0f; + uint64_t u = 0; + z_owned_string_t c; + + ze_deserializer_t deserializer = ze_deserializer_from_bytes(z_loan(payload)); + ze_deserializer_deserialize_float(&deserializer, &f); + assert(f == cs.f); + size_t num_elements0 = 0; + ze_deserializer_deserialize_sequence_length(&deserializer, &num_elements0); + assert(num_elements0 == 2); + for (size_t i = 0; i < 2; ++i) { + size_t num_elements1 = 0; + ze_deserializer_deserialize_sequence_length(&deserializer, &num_elements1); + assert(num_elements1 == 3); + for (size_t j = 0; j < 3; ++j) { + ze_deserializer_deserialize_uint64(&deserializer, &u); + assert(u == cs.u[i][j]); + } + } + ze_deserializer_deserialize_string(&deserializer, &c); + assert(strncmp(cs.c, z_string_data(z_loan(c)), z_string_len(z_loan(c))) == 0); + + z_drop(z_move(c)); + z_drop(z_move(payload)); + } +#endif + // Slice iterator + { + /// Fill z_bytes with some data + z_owned_bytes_t b1, b2, b3; + z_bytes_copy_from_str(&b1, "abc"); + z_bytes_copy_from_str(&b2, "def"); + z_bytes_copy_from_str(&b3, "hij"); + z_owned_bytes_writer_t writer; + z_bytes_writer_empty(&writer); + z_bytes_writer_append(z_loan_mut(writer), z_move(b1)); + z_bytes_writer_append(z_loan_mut(writer), z_move(b2)); + z_bytes_writer_append(z_loan_mut(writer), z_move(b3)); + + z_bytes_writer_finish(z_move(writer), &payload); + z_bytes_slice_iterator_t slice_iter = z_bytes_get_slice_iterator(z_bytes_loan(&payload)); + z_view_slice_t curr_slice; + while (z_bytes_slice_iterator_next(&slice_iter, &curr_slice)) { + printf("slice len: %d, slice data: '", (int)z_slice_len(z_view_slice_loan(&curr_slice))); + print_slice_data(&curr_slice); + printf("'\n"); + } + z_drop(z_move(payload)); } - z_free(kvp->data); + return 0; } static void print_slice_data(z_view_slice_t *slice) { diff --git a/examples/unix/c11/z_get.c b/examples/unix/c11/z_get.c index db0bf816a..e70cdacd1 100644 --- a/examples/unix/c11/z_get.c +++ b/examples/unix/c11/z_get.c @@ -38,7 +38,7 @@ void reply_handler(z_loaned_reply_t *reply, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t replystr; - z_bytes_deserialize_into_string(z_sample_payload(sample), &replystr); + z_bytes_to_string(z_sample_payload(sample), &replystr); printf(">> Received %s ('%.*s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(replystr)), @@ -47,7 +47,7 @@ void reply_handler(z_loaned_reply_t *reply, void *ctx) { } else { const z_loaned_reply_err_t *err = z_reply_err(reply); z_owned_string_t errstr; - z_bytes_deserialize_into_string(z_reply_err_payload(err), &errstr); + z_bytes_to_string(z_reply_err_payload(err), &errstr); printf(">> Received an error: %.*s\n", (int)z_string_len(z_loan(errstr)), z_string_data(z_loan(errstr))); z_drop(z_move(errstr)); } diff --git a/examples/unix/c11/z_get_attachment.c b/examples/unix/c11/z_get_attachment.c index 14f33524a..c9490447e 100644 --- a/examples/unix/c11/z_get_attachment.c +++ b/examples/unix/c11/z_get_attachment.c @@ -19,77 +19,27 @@ #include typedef struct kv_pair_t { - const char *key; - const char *value; -} kv_pair_t; - -typedef struct kv_pairs_tx_t { - const kv_pair_t *data; - uint32_t len; - uint32_t current_idx; -} kv_pairs_tx_t; - -typedef struct kv_pair_decoded_t { z_owned_string_t key; z_owned_string_t value; -} kv_pair_decoded_t; - -typedef struct kv_pairs_rx_t { - kv_pair_decoded_t *data; - uint32_t len; - uint32_t current_idx; -} kv_pairs_rx_t; - -#define KVP_LEN 16 +} kv_pair_t; #if Z_FEATURE_QUERY == 1 && Z_FEATURE_MULTI_THREAD == 1 static z_owned_condvar_t cond; static z_owned_mutex_t mutex; -bool create_attachment_iter(z_owned_bytes_t *kv_pair, void *context) { - kv_pairs_tx_t *kvs = (kv_pairs_tx_t *)(context); - z_owned_bytes_t k, v; - if (kvs->current_idx >= kvs->len) { - return false; - } else { - z_bytes_serialize_from_str(&k, kvs->data[kvs->current_idx].key); - z_bytes_serialize_from_str(&v, kvs->data[kvs->current_idx].value); - z_bytes_from_pair(kv_pair, z_move(k), z_move(v)); - kvs->current_idx++; - return true; - } -} - -void parse_attachment(kv_pairs_rx_t *kvp, const z_loaned_bytes_t *attachment) { - z_owned_bytes_t kv, first, second; - z_bytes_iterator_t iter = z_bytes_get_iterator(attachment); - - while (kvp->current_idx < kvp->len && z_bytes_iterator_next(&iter, &kv)) { - z_bytes_deserialize_into_pair(z_loan(kv), &first, &second); - z_bytes_deserialize_into_string(z_loan(first), &kvp->data[kvp->current_idx].key); - z_bytes_deserialize_into_string(z_loan(second), &kvp->data[kvp->current_idx].value); - z_bytes_drop(z_bytes_move(&first)); - z_bytes_drop(z_bytes_move(&second)); - z_bytes_drop(z_bytes_move(&kv)); - kvp->current_idx++; - } -} - -void print_attachment(kv_pairs_rx_t *kvp) { +void print_attachment(const kv_pair_t *kvp, size_t len) { printf(" with attachment:\n"); - for (uint32_t i = 0; i < kvp->current_idx; i++) { - printf(" %d: %.*s, %.*s\n", i, (int)z_string_len(z_loan(kvp->data[i].key)), - z_string_data(z_loan(kvp->data[i].key)), (int)z_string_len(z_loan(kvp->data[i].value)), - z_string_data(z_loan(kvp->data[i].value))); + for (size_t i = 0; i < len; i++) { + printf(" %zu: %.*s, %.*s\n", i, (int)z_string_len(z_loan(kvp[i].key)), z_string_data(z_loan(kvp[i].key)), + (int)z_string_len(z_loan(kvp[i].value)), z_string_data(z_loan(kvp[i].value))); } } -void drop_attachment(kv_pairs_rx_t *kvp) { - for (size_t i = 0; i < kvp->current_idx; i++) { - z_string_drop(z_string_move(&kvp->data[i].key)); - z_string_drop(z_string_move(&kvp->data[i].value)); +void drop_attachment(kv_pair_t *kvp, size_t len) { + for (size_t i = 0; i < len; i++) { + z_drop(z_move(kvp[i].key)); + z_drop(z_move(kvp[i].value)); } - z_free(kvp->data); } void reply_dropper(void *ctx) { @@ -106,25 +56,36 @@ void reply_handler(z_loaned_reply_t *reply, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t replystr; - z_bytes_deserialize_into_string(z_sample_payload(sample), &replystr); + z_bytes_to_string(z_sample_payload(sample), &replystr); z_owned_string_t encoding; z_encoding_to_string(z_sample_encoding(sample), &encoding); printf(">> Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(replystr)), z_string_data(z_loan(replystr))); printf(" with encoding: %.*s\n", (int)z_string_len(z_loan(encoding)), z_string_data(z_loan(encoding))); + z_drop(z_move(replystr)); + z_drop(z_move(encoding)); +#if defined(Z_FEATURE_UNSTABLE_API) // Check attachment - kv_pairs_rx_t kvp = { - .current_idx = 0, .len = KVP_LEN, .data = (kv_pair_decoded_t *)malloc(KVP_LEN * sizeof(kv_pair_decoded_t))}; - parse_attachment(&kvp, z_sample_attachment(sample)); - if (kvp.current_idx > 0) { - print_attachment(&kvp); + const z_loaned_bytes_t *attachment = z_sample_attachment(sample); + if (attachment == NULL) { + return; } - drop_attachment(&kvp); - - z_drop(z_move(replystr)); - z_drop(z_move(encoding)); + ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); + size_t attachment_len; + ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len); + kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); + for (size_t i = 0; i < attachment_len; ++i) { + ze_deserializer_deserialize_string(&deserializer, &kvp[i].key); + ze_deserializer_deserialize_string(&deserializer, &kvp[i].value); + } + if (attachment_len > 0) { + print_attachment(kvp, attachment_len); + } + drop_attachment(kvp, attachment_len); + free(kvp); +#endif } else { printf(">> Received an error\n"); } @@ -211,14 +172,24 @@ int main(int argc, char **argv) { opts.payload = z_bytes_move(&payload); } +#if defined(Z_FEATURE_UNSTABLE_API) // Add attachment value kv_pair_t kvs[1]; - kvs[0] = (kv_pair_t){.key = "test_key", .value = "test_value"}; - kv_pairs_tx_t ctx = (kv_pairs_tx_t){.data = kvs, .current_idx = 0, .len = 1}; + z_string_from_str(&kvs[0].key, "test_key", NULL, NULL); + z_string_from_str(&kvs[0].value, "test_value", NULL, NULL); z_owned_bytes_t attachment; - z_bytes_from_iter(&attachment, create_attachment_iter, (void *)&ctx); - opts.attachment = z_move(attachment); + ze_owned_serializer_t serializer; + ze_serializer_empty(&serializer); + ze_serializer_serialize_sequence_length(z_loan_mut(serializer), 2); + for (size_t i = 0; i < 1; ++i) { + ze_serializer_serialize_string(z_loan_mut(serializer), z_loan(kvs[i].key)); + ze_serializer_serialize_string(z_loan_mut(serializer), z_loan(kvs[i].value)); + } + drop_attachment(kvs, 1); + ze_serializer_finish(z_move(serializer), &attachment); + opts.attachment = z_move(attachment); +#endif // Add encoding value z_owned_encoding_t encoding; z_encoding_from_str(&encoding, "zenoh/string;utf8"); diff --git a/examples/unix/c11/z_get_channel.c b/examples/unix/c11/z_get_channel.c index 2871a4527..f827d1722 100644 --- a/examples/unix/c11/z_get_channel.c +++ b/examples/unix/c11/z_get_channel.c @@ -111,7 +111,7 @@ int main(int argc, char **argv) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t replystr; - z_bytes_deserialize_into_string(z_sample_payload(sample), &replystr); + z_bytes_to_string(z_sample_payload(sample), &replystr); printf(">> Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(replystr)), z_string_data(z_loan(replystr))); diff --git a/examples/unix/c11/z_pub.c b/examples/unix/c11/z_pub.c index 16a98e880..e2f735a46 100644 --- a/examples/unix/c11/z_pub.c +++ b/examples/unix/c11/z_pub.c @@ -114,7 +114,7 @@ int main(int argc, char **argv) { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); z_publisher_put(z_loan(pub), z_move(payload), NULL); } diff --git a/examples/unix/c11/z_pub_attachment.c b/examples/unix/c11/z_pub_attachment.c index 41deb9270..1f7ca272f 100644 --- a/examples/unix/c11/z_pub_attachment.c +++ b/examples/unix/c11/z_pub_attachment.c @@ -20,36 +20,15 @@ #include #include #include - -#include "zenoh-pico/system/platform.h" +#include typedef struct kv_pair_t { const char *key; const char *value; } kv_pair_t; -typedef struct kv_pairs_t { - const kv_pair_t *data; - uint32_t len; - uint32_t current_idx; -} kv_pairs_t; - #if Z_FEATURE_PUBLICATION == 1 -bool 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) { - return false; - } else { - z_bytes_serialize_from_str(&k, kvs->data[kvs->current_idx].key); - z_bytes_serialize_from_str(&v, kvs->data[kvs->current_idx].value); - z_bytes_from_pair(kv_pair, z_move(k), z_move(v)); - kvs->current_idx++; - return true; - } -} - int main(int argc, char **argv) { const char *keyexpr = "demo/example/zenoh-pico-pub"; char *const default_value = "Pub from Pico!"; @@ -134,13 +113,13 @@ int main(int argc, char **argv) { z_publisher_put_options_t options; z_publisher_put_options_default(&options); +#if defined(Z_FEATURE_UNSTABLE_API) // Allocate attachment kv_pair_t kvs[2]; kvs[0] = (kv_pair_t){.key = "source", .value = "C"}; +#endif z_owned_bytes_t attachment; - - // Allocate buffer - char buf_ind[16]; + z_bytes_empty(&attachment); // Create encoding z_owned_encoding_t encoding; @@ -159,15 +138,22 @@ int main(int argc, char **argv) { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); - + z_bytes_copy_from_str(&payload, buf); +#if defined(Z_FEATURE_UNSTABLE_API) // Add attachment value + char buf_ind[16]; sprintf(buf_ind, "%d", idx); 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_from_iter(&attachment, create_attachment_iter, (void *)&ctx); + ze_owned_serializer_t serializer; + ze_serializer_empty(&serializer); + ze_serializer_serialize_sequence_length(z_loan_mut(serializer), 2); + for (size_t i = 0; i < 2; ++i) { + ze_serializer_serialize_str(z_loan_mut(serializer), kvs[i].key); + ze_serializer_serialize_str(z_loan_mut(serializer), kvs[i].value); + } + ze_serializer_finish(z_move(serializer), &attachment); options.attachment = z_move(attachment); - +#endif // Add encoding value z_encoding_from_str(&encoding, "zenoh/string;utf8"); options.encoding = z_move(encoding); diff --git a/examples/unix/c11/z_pub_st.c b/examples/unix/c11/z_pub_st.c index 8b9c71191..01e1f722e 100644 --- a/examples/unix/c11/z_pub_st.c +++ b/examples/unix/c11/z_pub_st.c @@ -98,7 +98,7 @@ int main(int argc, char **argv) { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); z_publisher_put(z_loan(pub), z_move(payload), NULL); diff --git a/examples/unix/c11/z_pull.c b/examples/unix/c11/z_pull.c index 1c7be30d0..218e1ca30 100644 --- a/examples/unix/c11/z_pull.c +++ b/examples/unix/c11/z_pull.c @@ -92,7 +92,7 @@ int main(int argc, char **argv) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(z_loan(sample)), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(z_loan(sample)), &value); + z_bytes_to_string(z_sample_payload(z_loan(sample)), &value); printf(">> [Subscriber] Pulled ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/unix/c11/z_queryable.c b/examples/unix/c11/z_queryable.c index 09e12d1f0..df3322003 100644 --- a/examples/unix/c11/z_queryable.c +++ b/examples/unix/c11/z_queryable.c @@ -36,7 +36,7 @@ void query_handler(z_loaned_query_t *query, void *ctx) { z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(params)), z_string_data(z_loan(params))); // Process value z_owned_string_t payload_string; - z_bytes_deserialize_into_string(z_query_payload(query), &payload_string); + z_bytes_to_string(z_query_payload(query), &payload_string); if (z_string_len(z_loan(payload_string)) > 0) { printf(" with value '%.*s'\n", (int)z_string_len(z_loan(payload_string)), z_string_data(z_loan(payload_string))); diff --git a/examples/unix/c11/z_queryable_attachment.c b/examples/unix/c11/z_queryable_attachment.c index 7533f14e7..6609995f1 100644 --- a/examples/unix/c11/z_queryable_attachment.c +++ b/examples/unix/c11/z_queryable_attachment.c @@ -19,89 +19,28 @@ #include typedef struct kv_pair_t { - const char *key; - const char *value; -} kv_pair_t; - -typedef struct kv_pairs_tx_t { - const kv_pair_t *data; - uint32_t len; - uint32_t current_idx; -} kv_pairs_tx_t; - -typedef struct kv_pair_decoded_t { z_owned_string_t key; z_owned_string_t value; -} kv_pair_decoded_t; - -typedef struct kv_pairs_rx_t { - kv_pair_decoded_t *data; - uint32_t len; - uint32_t current_idx; -} kv_pairs_rx_t; - -#define KVP_LEN 16 +} kv_pair_t; #if Z_FEATURE_QUERYABLE == 1 const char *keyexpr = "demo/example/zenoh-pico-queryable"; const char *value = "Queryable from Pico!"; static int msg_nb = 0; -size_t kv_pairs_size(kv_pairs_tx_t *kvp) { - size_t ret = 0; - for (size_t i = 0; i < kvp->len; i++) { - // Size fields - ret += 2 * sizeof(uint32_t); - // Data size - ret += strlen(kvp->data[i].key) + strlen(kvp->data[i].value); - } - return ret; -} - -bool create_attachment_iter(z_owned_bytes_t *kv_pair, void *context) { - kv_pairs_tx_t *kvs = (kv_pairs_tx_t *)(context); - z_owned_bytes_t k, v; - if (kvs->current_idx >= kvs->len) { - return false; - } else { - z_bytes_serialize_from_str(&k, kvs->data[kvs->current_idx].key); - z_bytes_serialize_from_str(&v, kvs->data[kvs->current_idx].value); - z_bytes_from_pair(kv_pair, z_move(k), z_move(v)); - kvs->current_idx++; - return true; - } -} - -void parse_attachment(kv_pairs_rx_t *kvp, const z_loaned_bytes_t *attachment) { - z_owned_bytes_t kv, first, second; - z_bytes_iterator_t iter = z_bytes_get_iterator(attachment); - - while (kvp->current_idx < kvp->len && z_bytes_iterator_next(&iter, &kv)) { - z_bytes_deserialize_into_pair(z_loan(kv), &first, &second); - z_bytes_deserialize_into_string(z_loan(first), &kvp->data[kvp->current_idx].key); - z_bytes_deserialize_into_string(z_loan(second), &kvp->data[kvp->current_idx].value); - z_bytes_drop(z_bytes_move(&first)); - z_bytes_drop(z_bytes_move(&second)); - z_bytes_drop(z_bytes_move(&kv)); - kvp->current_idx++; - } -} - -void print_attachment(kv_pairs_rx_t *kvp) { +void print_attachment(const kv_pair_t *kvp, size_t len) { printf(" with attachment:\n"); - for (uint32_t i = 0; i < kvp->current_idx; i++) { - printf(" %d: %.*s, %.*s\n", i, (int)z_string_len(z_loan(kvp->data[i].key)), - z_string_data(z_loan(kvp->data[i].key)), (int)z_string_len(z_loan(kvp->data[i].value)), - z_string_data(z_loan(kvp->data[i].value))); + for (size_t i = 0; i < len; i++) { + printf(" %zu: %.*s, %.*s\n", i, (int)z_string_len(z_loan(kvp[i].key)), z_string_data(z_loan(kvp[i].key)), + (int)z_string_len(z_loan(kvp[i].value)), z_string_data(z_loan(kvp[i].value))); } } -void drop_attachment(kv_pairs_rx_t *kvp) { - for (size_t i = 0; i < kvp->current_idx; i++) { - z_string_drop(z_string_move(&kvp->data[i].key)); - z_string_drop(z_string_move(&kvp->data[i].value)); +void drop_attachment(kv_pair_t *kvp, size_t len) { + for (size_t i = 0; i < len; i++) { + z_drop(z_move(kvp[i].key)); + z_drop(z_move(kvp[i].value)); } - z_free(kvp->data); } void query_handler(z_loaned_query_t *query, void *ctx) { @@ -119,21 +58,32 @@ void query_handler(z_loaned_query_t *query, void *ctx) { // Process value z_owned_string_t payload_string; - z_bytes_deserialize_into_string(z_query_payload(query), &payload_string); + z_bytes_to_string(z_query_payload(query), &payload_string); if (z_string_len(z_loan(payload_string)) > 0) { printf(" with value '%.*s'\n", (int)z_string_len(z_loan(payload_string)), z_string_data(z_loan(payload_string))); } - // Check attachment - kv_pairs_rx_t kvp = { - .current_idx = 0, .len = KVP_LEN, .data = (kv_pair_decoded_t *)malloc(KVP_LEN * sizeof(kv_pair_decoded_t))}; - parse_attachment(&kvp, z_query_attachment(query)); - if (kvp.current_idx > 0) { - print_attachment(&kvp); - } - drop_attachment(&kvp); z_drop(z_move(payload_string)); z_drop(z_move(encoding)); +#if defined(Z_FEATURE_UNSTABLE_API) + // Check attachment + const z_loaned_bytes_t *attachment = z_query_attachment(query); + if (attachment != NULL) { + ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); + size_t attachment_len; + ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len); + kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); + for (size_t i = 0; i < attachment_len; ++i) { + ze_deserializer_deserialize_string(&deserializer, &kvp[i].key); + ze_deserializer_deserialize_string(&deserializer, &kvp[i].value); + } + if (attachment_len > 0) { + print_attachment(kvp, attachment_len); + } + drop_attachment(kvp, attachment_len); + free(kvp); + } +#endif // Reply payload z_owned_bytes_t reply_payload; @@ -141,15 +91,21 @@ void query_handler(z_loaned_query_t *query, void *ctx) { z_query_reply_options_t options; z_query_reply_options_default(&options); - +#if defined(Z_FEATURE_UNSTABLE_API) // Reply attachment + z_owned_bytes_t reply_attachment; kv_pair_t kvs[1]; - kvs[0] = (kv_pair_t){.key = "reply_key", .value = "reply_value"}; - kv_pairs_tx_t kv_ctx = (kv_pairs_tx_t){.data = kvs, .current_idx = 0, .len = 1}; - z_owned_bytes_t attachment; - z_bytes_from_iter(&attachment, create_attachment_iter, (void *)&kv_ctx); - options.attachment = z_move(attachment); - + z_string_from_str(&kvs[0].key, "reply_key", NULL, NULL); + z_string_from_str(&kvs[0].value, "reply_value", NULL, NULL); + ze_owned_serializer_t serializer; + ze_serializer_empty(&serializer); + ze_serializer_serialize_sequence_length(z_loan_mut(serializer), 1); + ze_serializer_serialize_string(z_loan_mut(serializer), z_loan(kvs[0].key)); + ze_serializer_serialize_string(z_loan_mut(serializer), z_loan(kvs[0].value)); + ze_serializer_finish(z_move(serializer), &reply_attachment); + options.attachment = z_move(reply_attachment); + drop_attachment(kvs, 1); +#endif // Reply encoding z_owned_encoding_t reply_encoding; z_encoding_from_str(&reply_encoding, "zenoh/string;utf8"); diff --git a/examples/unix/c11/z_queryable_channel.c b/examples/unix/c11/z_queryable_channel.c index 295ea09f3..eb6c94f46 100644 --- a/examples/unix/c11/z_queryable_channel.c +++ b/examples/unix/c11/z_queryable_channel.c @@ -108,7 +108,7 @@ int main(int argc, char **argv) { z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(params)), z_string_data(z_loan(params))); // Process value z_owned_string_t payload_string; - z_bytes_deserialize_into_string(z_query_payload(z_loan(query)), &payload_string); + z_bytes_to_string(z_query_payload(z_loan(query)), &payload_string); if (z_string_len(z_loan(payload_string)) > 0) { printf(" with value '%.*s'\n", (int)z_string_len(z_loan(payload_string)), z_string_data(z_loan(payload_string))); diff --git a/examples/unix/c11/z_sub.c b/examples/unix/c11/z_sub.c index c1f67c311..8f97bf900 100644 --- a/examples/unix/c11/z_sub.c +++ b/examples/unix/c11/z_sub.c @@ -29,7 +29,7 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(">> [Subscriber] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/unix/c11/z_sub_attachment.c b/examples/unix/c11/z_sub_attachment.c index 336f187ec..7ca79064b 100644 --- a/examples/unix/c11/z_sub_attachment.c +++ b/examples/unix/c11/z_sub_attachment.c @@ -26,48 +26,23 @@ typedef struct kv_pair_t { z_owned_string_t value; } kv_pair_t; -typedef struct kv_pairs_t { - kv_pair_t *data; - uint32_t len; - uint32_t current_idx; -} kv_pairs_t; - -#define KVP_LEN 16 - #if Z_FEATURE_SUBSCRIPTION == 1 static int msg_nb = 0; -void parse_attachment(kv_pairs_t *kvp, const z_loaned_bytes_t *attachment) { - z_owned_bytes_t kv, first, second; - z_bytes_iterator_t iter = z_bytes_get_iterator(attachment); - - while (kvp->current_idx < kvp->len && z_bytes_iterator_next(&iter, &kv)) { - z_bytes_deserialize_into_pair(z_loan(kv), &first, &second); - z_bytes_deserialize_into_string(z_loan(first), &kvp->data[kvp->current_idx].key); - z_bytes_deserialize_into_string(z_loan(second), &kvp->data[kvp->current_idx].value); - z_bytes_drop(z_bytes_move(&first)); - z_bytes_drop(z_bytes_move(&second)); - z_bytes_drop(z_bytes_move(&kv)); - kvp->current_idx++; - } -} - -void print_attachment(kv_pairs_t *kvp) { +void print_attachment(const kv_pair_t *kvp, size_t len) { printf(" with attachment:\n"); - for (uint32_t i = 0; i < kvp->current_idx; i++) { - printf(" %d: %.*s, %.*s\n", i, (int)z_string_len(z_loan(kvp->data[i].key)), - z_string_data(z_loan(kvp->data[i].key)), (int)z_string_len(z_loan(kvp->data[i].value)), - z_string_data(z_loan(kvp->data[i].value))); + for (size_t i = 0; i < len; i++) { + printf(" %zu: %.*s, %.*s\n", i, (int)z_string_len(z_loan(kvp[i].key)), z_string_data(z_loan(kvp[i].key)), + (int)z_string_len(z_loan(kvp[i].value)), z_string_data(z_loan(kvp[i].value))); } } -void drop_attachment(kv_pairs_t *kvp) { - for (size_t i = 0; i < kvp->current_idx; i++) { - z_string_drop(z_string_move(&kvp->data[i].key)); - z_string_drop(z_string_move(&kvp->data[i].value)); +void drop_attachment(kv_pair_t *kvp, size_t len) { + for (size_t i = 0; i < len; i++) { + z_drop(z_move(kvp[i].key)); + z_drop(z_move(kvp[i].value)); } - z_free(kvp->data); } void data_handler(z_loaned_sample_t *sample, void *ctx) { @@ -75,7 +50,7 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); z_owned_string_t encoding; z_encoding_to_string(z_sample_encoding(sample), &encoding); @@ -89,12 +64,25 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { printf(" with timestamp: %" PRIu64 "\n", z_timestamp_ntp64_time(ts)); } // Check attachment - kv_pairs_t kvp = {.current_idx = 0, .len = KVP_LEN, .data = (kv_pair_t *)malloc(KVP_LEN * sizeof(kv_pair_t))}; - parse_attachment(&kvp, z_sample_attachment(sample)); - if (kvp.current_idx > 0) { - print_attachment(&kvp); +#if defined(Z_FEATURE_UNSTABLE_API) + const z_loaned_bytes_t *attachment = z_sample_attachment(sample); + if (attachment != NULL) { + ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); + size_t attachment_len; + ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len); + kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); + for (size_t i = 0; i < attachment_len; ++i) { + ze_deserializer_deserialize_string(&deserializer, &kvp[i].key); + ze_deserializer_deserialize_string(&deserializer, &kvp[i].value); + } + if (attachment_len > 0) { + print_attachment(kvp, attachment_len); + } + drop_attachment(kvp, attachment_len); + free(kvp); } - drop_attachment(&kvp); +#endif + z_drop(z_move(value)); z_drop(z_move(encoding)); msg_nb++; diff --git a/examples/unix/c11/z_sub_channel.c b/examples/unix/c11/z_sub_channel.c index fa09b0f42..beda9d93b 100644 --- a/examples/unix/c11/z_sub_channel.c +++ b/examples/unix/c11/z_sub_channel.c @@ -82,7 +82,7 @@ int main(int argc, char **argv) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(z_loan(sample)), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(z_loan(sample)), &value); + z_bytes_to_string(z_sample_payload(z_loan(sample)), &value); printf(">> [Subscriber] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/unix/c11/z_sub_st.c b/examples/unix/c11/z_sub_st.c index 003b8a0fe..2cc0089f9 100644 --- a/examples/unix/c11/z_sub_st.c +++ b/examples/unix/c11/z_sub_st.c @@ -28,7 +28,7 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(">> [Subscriber] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/unix/c99/z_get.c b/examples/unix/c99/z_get.c index e672c2d0a..2be3b151d 100644 --- a/examples/unix/c99/z_get.c +++ b/examples/unix/c99/z_get.c @@ -36,7 +36,7 @@ void reply_handler(z_loaned_reply_t *reply, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t replystr; - z_bytes_deserialize_into_string(z_sample_payload(sample), &replystr); + z_bytes_to_string(z_sample_payload(sample), &replystr); printf(">> Received ('%.*s': '%.*s')\n", (int)z_string_len(z_view_string_loan(&keystr)), z_string_data(z_view_string_loan(&keystr)), (int)z_string_len(z_string_loan(&replystr)), diff --git a/examples/unix/c99/z_pub.c b/examples/unix/c99/z_pub.c index 10fb6d570..887d9ab08 100644 --- a/examples/unix/c99/z_pub.c +++ b/examples/unix/c99/z_pub.c @@ -104,7 +104,7 @@ int main(int argc, char **argv) { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); z_publisher_put(z_publisher_loan(&pub), z_bytes_move(&payload), NULL); } diff --git a/examples/unix/c99/z_pub_st.c b/examples/unix/c99/z_pub_st.c index ed22d29e5..af0f7fbfe 100644 --- a/examples/unix/c99/z_pub_st.c +++ b/examples/unix/c99/z_pub_st.c @@ -98,7 +98,7 @@ int main(int argc, char **argv) { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); z_publisher_put(z_publisher_loan(&pub), z_bytes_move(&payload), NULL); ++idx; diff --git a/examples/unix/c99/z_pull.c b/examples/unix/c99/z_pull.c index 283752d27..96bacef3c 100644 --- a/examples/unix/c99/z_pull.c +++ b/examples/unix/c99/z_pull.c @@ -96,7 +96,7 @@ int main(int argc, char **argv) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(z_sample_loan(&sample)), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(z_sample_loan(&sample)), &value); + z_bytes_to_string(z_sample_payload(z_sample_loan(&sample)), &value); printf(">> [Subscriber] Pulled ('%.*s': '%.*s')\n", (int)z_string_len(z_view_string_loan(&keystr)), z_string_data(z_view_string_loan(&keystr)), (int)z_string_len(z_string_loan(&value)), z_string_data(z_string_loan(&value))); diff --git a/examples/unix/c99/z_queryable.c b/examples/unix/c99/z_queryable.c index a8a676a20..4b9ab503c 100644 --- a/examples/unix/c99/z_queryable.c +++ b/examples/unix/c99/z_queryable.c @@ -33,7 +33,7 @@ void query_handler(z_loaned_query_t *query, void *ctx) { z_string_data(z_view_string_loan(¶ms))); // Process value z_owned_string_t payload_string; - z_bytes_deserialize_into_string(z_query_payload(query), &payload_string); + z_bytes_to_string(z_query_payload(query), &payload_string); if (z_string_len(z_string_loan(&payload_string)) > 1) { printf(" with value '%.*s'\n", (int)z_string_len(z_string_loan(&payload_string)), z_string_data(z_string_loan(&payload_string))); diff --git a/examples/unix/c99/z_sub.c b/examples/unix/c99/z_sub.c index 7094ff83b..e0e5d4d6b 100644 --- a/examples/unix/c99/z_sub.c +++ b/examples/unix/c99/z_sub.c @@ -25,7 +25,7 @@ void data_handler(z_loaned_sample_t *sample, void *arg) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(">> [Subscriber] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_view_string_loan(&keystr)), z_string_data(z_view_string_loan(&keystr)), (int)z_string_len(z_string_loan(&value)), z_string_data(z_string_loan(&value))); diff --git a/examples/unix/c99/z_sub_st.c b/examples/unix/c99/z_sub_st.c index 320c653d4..7f1f6042a 100644 --- a/examples/unix/c99/z_sub_st.c +++ b/examples/unix/c99/z_sub_st.c @@ -28,7 +28,7 @@ void data_handler(z_loaned_sample_t *sample, void *arg) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(">> [Subscriber] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_view_string_loan(&keystr)), z_string_data(z_view_string_loan(&keystr)), (int)z_string_len(z_string_loan(&value)), z_string_data(z_string_loan(&value))); diff --git a/examples/windows/z_get.c b/examples/windows/z_get.c index 46f588293..5a41b1bd3 100644 --- a/examples/windows/z_get.c +++ b/examples/windows/z_get.c @@ -35,7 +35,7 @@ void reply_handler(z_loaned_reply_t *reply, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t replystr; - z_bytes_deserialize_into_string(z_sample_payload(sample), &replystr); + z_bytes_to_string(z_sample_payload(sample), &replystr); printf(">> Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(replystr)), z_string_data(z_loan(replystr))); diff --git a/examples/windows/z_pub_st.c b/examples/windows/z_pub_st.c index 8f85bccab..028ed0dba 100644 --- a/examples/windows/z_pub_st.c +++ b/examples/windows/z_pub_st.c @@ -62,7 +62,7 @@ int main(int argc, char **argv) { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); z_publisher_put(z_loan(pub), z_move(payload), NULL); ++idx; diff --git a/examples/windows/z_pull.c b/examples/windows/z_pull.c index 41f8298b9..7067b1fce 100644 --- a/examples/windows/z_pull.c +++ b/examples/windows/z_pull.c @@ -66,7 +66,7 @@ int main(int argc, char **argv) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(z_loan(sample)), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(z_loan(sample)), &value); + z_bytes_to_string(z_sample_payload(z_loan(sample)), &value); printf(">> [Subscriber] Pulled ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/windows/z_queryable.c b/examples/windows/z_queryable.c index 7ab31a1b7..f5a6b63cc 100644 --- a/examples/windows/z_queryable.c +++ b/examples/windows/z_queryable.c @@ -32,7 +32,7 @@ void query_handler(z_loaned_query_t *query, void *ctx) { z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(params)), z_string_data(z_loan(params))); // Process value z_owned_string_t payload_string; - z_bytes_deserialize_into_string(z_query_payload(query), &payload_string); + z_bytes_to_string(z_query_payload(query), &payload_string); if (z_string_len(z_loan(payload_string)) > 0) { printf(" with value '%.*s'\n", (int)z_string_len(z_loan(payload_string)), z_string_data(z_loan(payload_string))); diff --git a/examples/windows/z_sub.c b/examples/windows/z_sub.c index d9d824aad..d27c40475 100644 --- a/examples/windows/z_sub.c +++ b/examples/windows/z_sub.c @@ -24,7 +24,7 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(">> [Subscriber] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/windows/z_sub_st.c b/examples/windows/z_sub_st.c index bcd675d29..9ba8dc768 100644 --- a/examples/windows/z_sub_st.c +++ b/examples/windows/z_sub_st.c @@ -27,7 +27,7 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(">> [Subscriber] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/zephyr/z_get.c b/examples/zephyr/z_get.c index d8e6830f9..874489b03 100644 --- a/examples/zephyr/z_get.c +++ b/examples/zephyr/z_get.c @@ -40,7 +40,7 @@ void reply_handler(z_loaned_reply_t *oreply, void *ctx) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t replystr; - z_bytes_deserialize_into_string(z_sample_payload(sample), &replystr); + z_bytes_to_string(z_sample_payload(sample), &replystr); printf(" >> Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(replystr)), z_string_data(z_loan(replystr))); diff --git a/examples/zephyr/z_pub.c b/examples/zephyr/z_pub.c index 7a4cf120e..2ad4f7bb3 100644 --- a/examples/zephyr/z_pub.c +++ b/examples/zephyr/z_pub.c @@ -74,7 +74,7 @@ int main(int argc, char **argv) { // Create payload z_owned_bytes_t payload; - z_bytes_serialize_from_str(&payload, buf); + z_bytes_copy_from_str(&payload, buf); z_publisher_put(z_loan(pub), z_move(payload), NULL); } diff --git a/examples/zephyr/z_pull.c b/examples/zephyr/z_pull.c index 335c2fcc8..447cce6bf 100644 --- a/examples/zephyr/z_pull.c +++ b/examples/zephyr/z_pull.c @@ -79,7 +79,7 @@ int main(int argc, char **argv) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(z_loan(sample)), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(z_loan(sample)), &value); + z_bytes_to_string(z_sample_payload(z_loan(sample)), &value); printf(">> [Subscriber] Pulled ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/examples/zephyr/z_queryable.c b/examples/zephyr/z_queryable.c index c763a804b..66e53bca9 100644 --- a/examples/zephyr/z_queryable.c +++ b/examples/zephyr/z_queryable.c @@ -41,7 +41,7 @@ void query_handler(z_loaned_query_t *query, void *ctx) { z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(params)), z_string_data(z_loan(params))); // Process value z_owned_string_t payload_string; - z_bytes_deserialize_into_string(z_query_payload(query), &payload_string); + z_bytes_to_string(z_query_payload(query), &payload_string); if (z_string_len(z_loan(payload_string)) > 0) { printf(" with value '%.*s'\n", (int)z_string_len(z_loan(payload_string)), z_string_data(z_loan(payload_string))); diff --git a/examples/zephyr/z_sub.c b/examples/zephyr/z_sub.c index 780916b97..6616e2f1f 100644 --- a/examples/zephyr/z_sub.c +++ b/examples/zephyr/z_sub.c @@ -33,7 +33,7 @@ void data_handler(z_loaned_sample_t *sample, void *arg) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); printf(" >> [Subscriber handler] Received ('%.*s': '%.*s')\n", (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)z_string_len(z_loan(value)), z_string_data(z_loan(value))); z_drop(z_move(value)); diff --git a/include/zenoh-pico/api/macros.h b/include/zenoh-pico/api/macros.h index 9ca304f41..1a1363afd 100644 --- a/include/zenoh-pico/api/macros.h +++ b/include/zenoh-pico/api/macros.h @@ -16,6 +16,7 @@ #include "zenoh-pico/api/handlers.h" #include "zenoh-pico/api/primitives.h" +#include "zenoh-pico/api/serialization.h" #include "zenoh-pico/api/types.h" #if ZENOH_C_STANDARD != 99 @@ -23,7 +24,11 @@ #ifndef __cplusplus // clang-format off - +#if defined (Z_FEATURE_UNSTABLE_API) +#define __ZP_ZE_LOAN ze_owned_serializer_t : ze_serializer_loan, +#else +#define __ZP_ZE_LOAN +#endif /** * Defines a generic function for loaning any of the ``z_owned_X_t`` types. * @@ -67,9 +72,18 @@ z_owned_closure_reply_t : z_closure_reply_loan, \ z_owned_closure_query_t : z_closure_query_loan, \ z_owned_closure_hello_t : z_closure_hello_loan, \ - z_owned_closure_zid_t : z_closure_zid_loan \ + z_owned_closure_zid_t : z_closure_zid_loan, \ + __ZP_ZE_LOAN \ + z_owned_bytes_writer_t : z_bytes_writer_loan \ )(&x) + +#if defined (Z_FEATURE_UNSTABLE_API) +#define __ZP_ZE_LOAN_MUT ze_owned_serializer_t : ze_serializer_loan_mut , +#else +#define __ZP_ZE_LOAN_MUT +#endif + \ #define z_loan_mut(x) _Generic((x), \ z_owned_keyexpr_t : z_keyexpr_loan_mut, \ z_owned_config_t : z_config_loan_mut, \ @@ -89,8 +103,18 @@ z_owned_task_t : z_task_loan_mut, \ z_owned_mutex_t : z_mutex_loan_mut, \ z_owned_condvar_t : z_condvar_loan_mut, \ - z_owned_reply_err_t : z_reply_err_loan_mut \ + z_owned_reply_err_t : z_reply_err_loan_mut, \ + __ZP_ZE_LOAN_MUT \ + z_owned_bytes_writer_t : z_bytes_writer_loan_mut \ )(&x) + + +#if defined (Z_FEATURE_UNSTABLE_API) +#define __ZP_ZE_DROP ze_moved_serializer_t* : ze_serializer_drop, +#else +#define __ZP_ZE_DROP +#endif + /** * Defines a generic function for dropping any of the ``z_owned_X_t`` types. * @@ -127,9 +151,18 @@ z_moved_ring_handler_query_t* : z_ring_handler_query_drop, \ z_moved_ring_handler_reply_t* : z_ring_handler_reply_drop, \ z_moved_ring_handler_sample_t* : z_ring_handler_sample_drop, \ - z_moved_reply_err_t* : z_reply_err_drop \ + z_moved_reply_err_t* : z_reply_err_drop, \ + __ZP_ZE_DROP \ + z_moved_bytes_writer_t* : z_bytes_writer_drop \ )(x) + +#if defined (Z_FEATURE_UNSTABLE_API) +#define __ZP_ZE_CHECK ze_owned_serializer_t : ze_internal_serializer_check, +#else +#define __ZP_ZE_CHECK +#endif + /** * Defines a generic function for checking the validity of any of the ``z_owned_X_t`` types. * @@ -161,7 +194,9 @@ z_owned_bytes_t : z_internal_bytes_check, \ z_owned_sample_t : z_internal_sample_check, \ z_owned_query_t : z_internal_query_check, \ - z_owned_encoding_t : z_internal_encoding_check \ + z_owned_encoding_t : z_internal_encoding_check, \ + __ZP_ZE_CHECK \ + z_owned_bytes_writer_t : z_internal_bytes_writer_check \ )(&x) /** @@ -198,6 +233,12 @@ const z_loaned_ring_handler_sample_t* : z_ring_handler_sample_recv \ )(x, __VA_ARGS__) +#if defined (Z_FEATURE_UNSTABLE_API) +#define __ZP_ZE_MOVE ze_owned_serializer_t : ze_serializer_move, +#else +#define __ZP_ZE_MOVE +#endif + /** * Defines a generic function for moving any of the ``z_owned_X_t`` types. * @@ -237,9 +278,17 @@ z_owned_fifo_handler_query_t : z_fifo_handler_query_move, \ z_owned_fifo_handler_reply_t : z_fifo_handler_reply_move, \ z_owned_fifo_handler_sample_t : z_fifo_handler_sample_move, \ - z_owned_reply_err_t : z_reply_err_move \ + z_owned_reply_err_t : z_reply_err_move, \ + __ZP_ZE_MOVE \ + z_owned_bytes_writer_t : z_bytes_writer_move \ )(&x) +#if defined (Z_FEATURE_UNSTABLE_API) +#define __ZP_ZE_TAKE ze_owned_serializer_t *: ze_serializer_take, +#else +#define __ZP_ZE_TAKE +#endif + /** * Defines a generic function for extracting the ``z_owned_X_t`` type from ``z_moved_X_t`` * @@ -280,7 +329,9 @@ z_owned_slice_t *: z_slice_take, \ z_owned_string_array_t *: z_string_array_take, \ z_owned_string_t *: z_string_take, \ - z_owned_subscriber_t *: z_subscriber_take \ + z_owned_subscriber_t *: z_subscriber_take, \ + __ZP_ZE_TAKE \ + z_owned_bytes_writer_t *: z_bytes_writer_take \ )(this_, x) /** @@ -308,6 +359,12 @@ z_owned_config_t* : z_config_clone \ )(x, y) +#if defined (Z_FEATURE_UNSTABLE_API) +#define __ZP_ZE_NULL ze_owned_serializer_t * : ze_internal_serializer_null, +#else +#define __ZP_ZE_NULL +#endif + /** * Defines a generic function for making null object of any of the ``z_owned_X_t`` types. * @@ -335,7 +392,9 @@ z_owned_closure_zid_t * : z_internal_closure_zid_null, \ z_owned_sample_t * : z_internal_sample_null, \ z_owned_encoding_t * : z_internal_encoding_null, \ - z_owned_reply_err_t * : z_internal_reply_err_null \ + z_owned_reply_err_t * : z_internal_reply_err_null, \ + __ZP_ZE_NULL \ + z_owned_bytes_writer_t * : z_internal_bytes_writer_null \ )(x) // clang-format on @@ -398,6 +457,10 @@ inline const z_loaned_fifo_handler_sample_t* z_loan(const z_owned_fifo_handler_s inline const z_loaned_ring_handler_query_t* z_loan(const z_owned_ring_handler_query_t& x) { return z_ring_handler_query_loan(&x); }; inline const z_loaned_ring_handler_reply_t* z_loan(const z_owned_ring_handler_reply_t& x) { return z_ring_handler_reply_loan(&x); }; inline const z_loaned_ring_handler_sample_t* z_loan(const z_owned_ring_handler_sample_t& x) { return z_ring_handler_sample_loan(&x); }; +inline const z_loaned_bytes_writer_t* z_loan(const z_owned_bytes_writer_t& x) { return z_bytes_writer_loan(&x); }; +#if defined(Z_FEATURE_UNSTABLE_API) +inline const ze_loaned_serializer_t* z_loan(const ze_owned_serializer_t& x) { return ze_serializer_loan(&x); }; +#endif // z_loan_mut definition inline z_loaned_keyexpr_t* z_loan_mut(z_owned_keyexpr_t& x) { return z_keyexpr_loan_mut(&x); } @@ -421,6 +484,10 @@ inline z_loaned_task_t* z_loan_mut(z_owned_task_t& x) { return z_task_loan_mut(& inline z_loaned_mutex_t* z_loan_mut(z_owned_mutex_t& x) { return z_mutex_loan_mut(&x); } inline z_loaned_condvar_t* z_loan_mut(z_owned_condvar_t& x) { return z_condvar_loan_mut(&x); } inline z_loaned_reply_err_t* z_loan_mut(z_owned_reply_err_t& x) { return z_reply_err_loan_mut(&x); } +inline z_loaned_bytes_writer_t* z_loan_mut(z_owned_bytes_writer_t& x) { return z_bytes_writer_loan_mut(&x); }; +#if defined(Z_FEATURE_UNSTABLE_API) +inline ze_loaned_serializer_t* z_loan_mut(ze_owned_serializer_t& x) { return ze_serializer_loan_mut(&x); }; +#endif // z_drop definition inline void z_drop(z_moved_session_t* v) { z_session_drop(v); } @@ -452,6 +519,10 @@ inline void z_drop(z_moved_ring_handler_query_t* v) { z_ring_handler_query_drop( inline void z_drop(z_moved_fifo_handler_query_t* v) { z_fifo_handler_query_drop(v); } inline void z_drop(z_moved_ring_handler_reply_t* v) { z_ring_handler_reply_drop(v); } inline void z_drop(z_moved_fifo_handler_reply_t* v) { z_fifo_handler_reply_drop(v); } +inline void z_drop(z_moved_bytes_writer_t* v) { z_bytes_writer_drop(v); } +#if defined(Z_FEATURE_UNSTABLE_API) +inline void z_drop(ze_moved_serializer_t* v) { ze_serializer_drop(v); } +#endif // z_internal_null definition inline void z_internal_null(z_owned_session_t* v) { z_internal_session_null(v); } @@ -479,6 +550,10 @@ inline void z_internal_null(z_owned_ring_handler_sample_t* v) { return z_interna inline void z_internal_null(z_owned_fifo_handler_query_t* v) { return z_internal_fifo_handler_query_null(v); }; inline void z_internal_null(z_owned_fifo_handler_reply_t* v) { return z_internal_fifo_handler_reply_null(v); }; inline void z_internal_null(z_owned_fifo_handler_sample_t* v) { return z_internal_fifo_handler_sample_null(v); }; +inline void z_internal_null(z_owned_bytes_writer_t* v) { return z_internal_bytes_writer_null(v); }; +#if defined(Z_FEATURE_UNSTABLE_API) +inline void z_internal_null(ze_owned_serializer_t* v) { return ze_internal_serializer_null(v); }; +#endif // z_internal_check definition inline bool z_internal_check(const z_owned_session_t& v) { return z_internal_session_check(&v); } @@ -501,6 +576,10 @@ inline bool z_internal_check(const z_owned_fifo_handler_sample_t& v) { return z_ inline bool z_internal_check(const z_owned_ring_handler_query_t& v) { return z_internal_ring_handler_query_check(&v); }; inline bool z_internal_check(const z_owned_ring_handler_reply_t& v) { return z_internal_ring_handler_reply_check(&v); }; inline bool z_internal_check(const z_owned_ring_handler_sample_t& v) { return z_internal_ring_handler_sample_check(&v); }; +inline bool z_internal_check(const z_owned_bytes_writer_t& v) { return z_internal_bytes_writer_check(&v); }; +#if defined(Z_FEATURE_UNSTABLE_API) +inline bool z_internal_check(const ze_owned_serializer_t& v) { return ze_internal_serializer_check(&v); }; +#endif // z_call definition inline void z_call(const z_loaned_closure_sample_t &closure, z_loaned_sample_t *sample) @@ -632,6 +711,10 @@ inline z_moved_ring_handler_reply_t* z_move(z_owned_ring_handler_reply_t& x) { r inline z_moved_ring_handler_sample_t* z_move(z_owned_ring_handler_sample_t& x) { return z_ring_handler_sample_move(&x); }; +inline z_moved_bytes_writer_t* z_move(z_owned_bytes_writer_t& x) { return z_bytes_writer_move(&x); }; +#if defined(Z_FEATURE_UNSTABLE_API) +inline ze_moved_serializer_t* z_move(ze_owned_serializer_t& x) { return ze_serializer_move(&x); }; +#endif // z_take definition inline void z_take(z_owned_session_t* this_, z_moved_session_t* v) { return z_session_take(this_, v); } @@ -675,6 +758,10 @@ inline void z_take(z_owned_ring_handler_reply_t* this_, z_moved_ring_handler_rep inline void z_take(z_owned_fifo_handler_reply_t* this_, z_moved_fifo_handler_reply_t* v) { z_fifo_handler_reply_take(this_, v); } +inline void z_take(z_owned_bytes_writer_t* this_, z_moved_bytes_writer_t* v) { z_bytes_writer_take(this_, v); } +#if defined(Z_FEATURE_UNSTABLE_API) +inline void z_take(ze_owned_serializer_t* this_, ze_moved_serializer_t* v) { ze_serializer_take(this_, v); } +#endif // z_clone definition inline z_result_t z_clone(z_owned_bytes_t* dst, z_loaned_bytes_t* this_) { return z_bytes_clone(dst, this_); }; @@ -915,6 +1002,25 @@ template <> struct z_owned_to_loaned_type_t { typedef z_loaned_ring_handler_sample_t type; }; +template <> +struct z_loaned_to_owned_type_t { + typedef z_owned_bytes_writer_t type; +}; +template <> +struct z_owned_to_loaned_type_t { + typedef z_loaned_bytes_writer_t type; +}; +#if defined(Z_FEATURE_UNSTABLE_API) +template <> +struct z_loaned_to_owned_type_t { + typedef ze_owned_serializer_t type; +}; +template <> +struct z_owned_to_loaned_type_t { + typedef ze_loaned_serializer_t type; +}; +#endif + #endif #endif /* ZENOH_C_STANDARD != 99 */ diff --git a/include/zenoh-pico/api/olv_macros.h b/include/zenoh-pico/api/olv_macros.h index 006fd2024..ffa82285c 100644 --- a/include/zenoh-pico/api/olv_macros.h +++ b/include/zenoh-pico/api/olv_macros.h @@ -27,52 +27,53 @@ // // !!! FOR INTERNAL USAGE ONLY !!! -#define _Z_MOVED_TYPE(name) \ - typedef struct { \ - z_owned_##name##_t _this; \ - } z_moved_##name##_t; +#define _Z_MOVED_TYPE_PREFIX(prefix, name) \ + typedef struct { \ + prefix##_owned_##name##_t _this; \ + } prefix##_moved_##name##_t; -#define _Z_LOANED_TYPE(type, name) typedef type z_loaned_##name##_t; +#define _Z_LOANED_TYPE_PREFIX(prefix, type, name) typedef type prefix##_loaned_##name##_t; // For value types -#define _Z_OWNED_TYPE_VALUE(type, name) \ - typedef struct { \ - type _val; \ - } z_owned_##name##_t; \ - _Z_LOANED_TYPE(type, name) \ - _Z_MOVED_TYPE(name) +#define _Z_OWNED_TYPE_VALUE_PREFIX(prefix, type, name) \ + typedef struct { \ + type _val; \ + } prefix##_owned_##name##_t; \ + _Z_LOANED_TYPE_PREFIX(prefix, type, name) \ + _Z_MOVED_TYPE_PREFIX(prefix, name) + +#define _Z_OWNED_TYPE_VALUE(type, name) _Z_OWNED_TYPE_VALUE_PREFIX(z, type, name) // For refcounted types -#define _Z_OWNED_TYPE_RC(type, name) \ - typedef struct { \ - type _rc; \ - } z_owned_##name##_t; \ - _Z_LOANED_TYPE(type, name) \ - _Z_MOVED_TYPE(name) +#define _Z_OWNED_TYPE_RC_PREFIX(prefix, type, name) \ + typedef struct { \ + type _rc; \ + } prefix##_owned_##name##_t; \ + _Z_LOANED_TYPE_PREFIX(prefix, type, name) \ + _Z_MOVED_TYPE_PREFIX(prefix, name) + +#define _Z_OWNED_TYPE_RC(type, name) _Z_OWNED_TYPE_RC_PREFIX(z, type, name) #define _Z_VIEW_TYPE(type, name) \ typedef struct { \ type _val; \ } z_view_##name##_t; -#define _Z_OWNED_FUNCTIONS_DEF(name) \ - void z_internal_##name##_null(z_owned_##name##_t *obj); \ - bool z_internal_##name##_check(const z_owned_##name##_t *obj); \ - const z_loaned_##name##_t *z_##name##_loan(const z_owned_##name##_t *obj); \ - z_loaned_##name##_t *z_##name##_loan_mut(z_owned_##name##_t *obj); \ - z_moved_##name##_t *z_##name##_move(z_owned_##name##_t *obj); \ - void z_##name##_take(z_owned_##name##_t *obj, z_moved_##name##_t *src); \ - z_result_t z_##name##_clone(z_owned_##name##_t *obj, const z_loaned_##name##_t *src); \ - void z_##name##_drop(z_moved_##name##_t *obj); - -#define _Z_OWNED_FUNCTIONS_NO_COPY_DEF(name) \ - void z_internal_##name##_null(z_owned_##name##_t *obj); \ - bool z_internal_##name##_check(const z_owned_##name##_t *obj); \ - const z_loaned_##name##_t *z_##name##_loan(const z_owned_##name##_t *obj); \ - z_loaned_##name##_t *z_##name##_loan_mut(z_owned_##name##_t *obj); \ - z_moved_##name##_t *z_##name##_move(z_owned_##name##_t *obj); \ - void z_##name##_take(z_owned_##name##_t *obj, z_moved_##name##_t *src); \ - void z_##name##_drop(z_moved_##name##_t *obj); +#define _Z_OWNED_FUNCTIONS_NO_COPY_DEF_PREFIX(prefix, name) \ + void prefix##_internal_##name##_null(prefix##_owned_##name##_t *obj); \ + bool prefix##_internal_##name##_check(const prefix##_owned_##name##_t *obj); \ + const prefix##_loaned_##name##_t *prefix##_##name##_loan(const prefix##_owned_##name##_t *obj); \ + prefix##_loaned_##name##_t *prefix##_##name##_loan_mut(prefix##_owned_##name##_t *obj); \ + prefix##_moved_##name##_t *prefix##_##name##_move(prefix##_owned_##name##_t *obj); \ + void prefix##_##name##_take(prefix##_owned_##name##_t *obj, prefix##_moved_##name##_t *src); \ + void prefix##_##name##_drop(prefix##_moved_##name##_t *obj); + +#define _Z_OWNED_FUNCTIONS_DEF_PREFIX(prefix, name) \ + _Z_OWNED_FUNCTIONS_NO_COPY_DEF_PREFIX(prefix, name) \ + z_result_t prefix##_##name##_clone(prefix##_owned_##name##_t *obj, const prefix##_loaned_##name##_t *src); + +#define _Z_OWNED_FUNCTIONS_NO_COPY_DEF(name) _Z_OWNED_FUNCTIONS_NO_COPY_DEF_PREFIX(z, name) +#define _Z_OWNED_FUNCTIONS_DEF(name) _Z_OWNED_FUNCTIONS_DEF_PREFIX(z, name) #define _Z_OWNED_FUNCTIONS_SYSTEM_DEF(name) \ void z_internal_##name##_null(z_owned_##name##_t *obj); \ @@ -87,47 +88,56 @@ z_loaned_##name##_t *z_view_##name##_loan_mut(z_view_##name##_t *name); \ void z_view_##name##_empty(z_view_##name##_t *name); -#define _Z_OWNED_FUNCTIONS_IMPL_MOVE_TAKE(name) \ - z_moved_##name##_t *z_##name##_move(z_owned_##name##_t *obj) { return (z_moved_##name##_t *)(obj); } \ - void z_##name##_take(z_owned_##name##_t *obj, z_moved_##name##_t *src) { \ - *obj = src->_this; \ - z_internal_##name##_null(&src->_this); \ - } +#define _ZP_NOTHING -#define _Z_OWNED_FUNCTIONS_VALUE_IMPL(type, name, f_check, f_null, f_copy, f_drop) \ - _Z_OWNED_FUNCTIONS_IMPL_MOVE_TAKE(name) \ - void z_internal_##name##_null(z_owned_##name##_t *obj) { obj->_val = f_null(); } \ - bool z_internal_##name##_check(const z_owned_##name##_t *obj) { return f_check((&obj->_val)); } \ - const z_loaned_##name##_t *z_##name##_loan(const z_owned_##name##_t *obj) { return &obj->_val; } \ - z_loaned_##name##_t *z_##name##_loan_mut(z_owned_##name##_t *obj) { return &obj->_val; } \ - z_result_t z_##name##_clone(z_owned_##name##_t *obj, const z_loaned_##name##_t *src) { \ - return f_copy((&obj->_val), src); \ - } \ - void z_##name##_drop(z_moved_##name##_t *obj) { \ - if (obj != NULL) f_drop((&obj->_this._val)); \ +#define _Z_OWNED_FUNCTIONS_IMPL_MOVE_TAKE_PREFIX_INNER(prefix, name, attribute) \ + attribute prefix##_moved_##name##_t *prefix##_##name##_move(prefix##_owned_##name##_t *obj) { \ + return (prefix##_moved_##name##_t *)(obj); \ + } \ + attribute void prefix##_##name##_take(prefix##_owned_##name##_t *obj, prefix##_moved_##name##_t *src) { \ + *obj = src->_this; \ + prefix##_internal_##name##_null(&src->_this); \ } -#define _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL_INNER(type, name, f_check, f_null, f_drop, attribute) \ - attribute void z_internal_##name##_null(z_owned_##name##_t *obj) { obj->_val = f_null(); } \ - attribute bool z_internal_##name##_check(const z_owned_##name##_t *obj) { return f_check((&obj->_val)); } \ - attribute const z_loaned_##name##_t *z_##name##_loan(const z_owned_##name##_t *obj) { return &obj->_val; } \ - attribute z_loaned_##name##_t *z_##name##_loan_mut(z_owned_##name##_t *obj) { return &obj->_val; } \ - attribute z_moved_##name##_t *z_##name##_move(z_owned_##name##_t *obj) { return (z_moved_##name##_t *)(obj); } \ - attribute void z_##name##_take(z_owned_##name##_t *obj, z_moved_##name##_t *src) { \ - *obj = src->_this; \ - z_internal_##name##_null(&src->_this); \ +#define _Z_OWNED_FUNCTIONS_IMPL_MOVE_TAKE(name) _Z_OWNED_FUNCTIONS_IMPL_MOVE_TAKE_PREFIX_INNER(z, name, _ZP_NOTHING) + +#define _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL_PREFIX_INNER(prefix, type, name, f_check, f_null, f_drop, attribute) \ + attribute void prefix##_internal_##name##_null(prefix##_owned_##name##_t *obj) { obj->_val = f_null(); } \ + _Z_OWNED_FUNCTIONS_IMPL_MOVE_TAKE_PREFIX_INNER(prefix, name, attribute) \ + attribute bool prefix##_internal_##name##_check(const prefix##_owned_##name##_t *obj) { \ + return f_check((&obj->_val)); \ + } \ + attribute const prefix##_loaned_##name##_t *prefix##_##name##_loan(const prefix##_owned_##name##_t *obj) { \ + return &obj->_val; \ + } \ + attribute prefix##_loaned_##name##_t *prefix##_##name##_loan_mut(prefix##_owned_##name##_t *obj) { \ + return &obj->_val; \ } \ - attribute void z_##name##_drop(z_moved_##name##_t *obj) { \ + attribute void prefix##_##name##_drop(prefix##_moved_##name##_t *obj) { \ if (obj != NULL) f_drop((&obj->_this._val)); \ } -#define _ZP_NOTHING +#define _Z_OWNED_FUNCTIONS_VALUE_IMPL_PREFIX_INNER(prefix, type, name, f_check, f_null, f_copy, f_drop, attribute) \ + _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL_PREFIX_INNER(prefix, type, name, f_check, f_null, f_drop, attribute) \ + attribute prefix##_result_t prefix##_##name##_clone(prefix##_owned_##name##_t *obj, \ + const prefix##_loaned_##name##_t *src) { \ + return f_copy((&obj->_val), src); \ + } + +#define _Z_OWNED_FUNCTIONS_VALUE_IMP_PREFIX(prefix, type, name, f_check, f_null, f_copy, f_drop) \ + _Z_OWNED_FUNCTIONS_VALUE_IMPL_PREFIX_INNER(z, type, name, f_check, f_null, f_copy, f_drop, _ZP_NOTHING) + +#define _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL_PREFIX(prefix, type, name, f_check, f_null, f_drop) \ + _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL_PREFIX_INNER(prefix, type, name, f_check, f_null, f_drop, _ZP_NOTHING) #define _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL(type, name, f_check, f_null, f_drop) \ - _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL_INNER(type, name, f_check, f_null, f_drop, _ZP_NOTHING) + _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL_PREFIX(z, type, name, f_check, f_null, f_drop) + +#define _Z_OWNED_FUNCTIONS_VALUE_IMPL(type, name, f_check, f_null, f_copy, f_drop) \ + _Z_OWNED_FUNCTIONS_VALUE_IMP_PREFIX(z, type, name, f_check, f_null, f_copy, f_drop) #define _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_INLINE_IMPL(type, name, f_check, f_null, f_drop) \ - _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL_INNER(type, name, f_check, f_null, f_drop, static inline) + _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL_PREFIX_INNER(z, type, name, f_check, f_null, f_drop, static inline) #define _Z_OWNED_FUNCTIONS_RC_IMPL(name) \ _Z_OWNED_FUNCTIONS_IMPL_MOVE_TAKE(name) \ diff --git a/include/zenoh-pico/api/primitives.h b/include/zenoh-pico/api/primitives.h index 14f298cf4..05c6a3dfc 100644 --- a/include/zenoh-pico/api/primitives.h +++ b/include/zenoh-pico/api/primitives.h @@ -508,127 +508,7 @@ size_t z_slice_len(const z_loaned_slice_t *slice); bool z_slice_is_empty(const z_loaned_slice_t *slice); /** - * Decodes data into a `int8_t` signed integer. - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * dst: Pointer to an uninitialized :c:type:`int8_t` to contain the decoded int. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_int8(const z_loaned_bytes_t *bytes, int8_t *dst); - -/** - * Decodes data into a `int16_t` signed integer. - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * dst: Pointer to an uninitialized :c:type:`int16_t` to contain the decoded int. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_int16(const z_loaned_bytes_t *bytes, int16_t *dst); - -/** - * Decodes data into a `int32_t` signed integer. - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * dst: Pointer to an uninitialized :c:type:`int32_t` to contain the decoded int. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_int32(const z_loaned_bytes_t *bytes, int32_t *dst); - -/** - * Decodes data into a `int64_t` signed integer. - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * dst: Pointer to an uninitialized :c:type:`int64_t` to contain the decoded int. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_int64(const z_loaned_bytes_t *bytes, int64_t *dst); - -/** - * Decodes data into a `uint8_t` unsigned integer. - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * dst: Pointer to an uninitialized :c:type:`uint8_t` to contain the decoded int. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_uint8(const z_loaned_bytes_t *bytes, uint8_t *dst); - -/** - * Decodes data into a `uint16_t` unsigned integer. - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * dst: Pointer to an uninitialized :c:type:`uint16_t` to contain the decoded int. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_uint16(const z_loaned_bytes_t *bytes, uint16_t *dst); - -/** - * Decodes data into a `uint32_t` unsigned integer. - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * dst: Pointer to an uninitialized :c:type:`uint32_t` to contain the decoded int. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_uint32(const z_loaned_bytes_t *bytes, uint32_t *dst); - -/** - * Decodes data into a `uint64_t` unsigned integer. - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * dst: Pointer to an uninitialized :c:type:`uint64_t` to contain the decoded int. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_uint64(const z_loaned_bytes_t *bytes, uint64_t *dst); - -/** - * Decodes data into a `float` floating number. - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * dst: Pointer to an uninitialized :c:type:`float` to contain the decoded float. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_float(const z_loaned_bytes_t *bytes, float *dst); - -/** - * Decodes data into a `double` floating number. - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * dst: Pointer to an uninitialized :c:type:`double` to contain the decoded float. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_double(const z_loaned_bytes_t *bytes, double *dst); - -/** - * Decodes data into a :c:type:`z_owned_slice_t` + * Converts data into a :c:type:`z_owned_slice_t` * * Parameters: * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. @@ -637,10 +517,10 @@ z_result_t z_bytes_deserialize_into_double(const z_loaned_bytes_t *bytes, double * Return: * ``0`` if decode successful, or a ``negative value`` otherwise. */ -z_result_t z_bytes_deserialize_into_slice(const z_loaned_bytes_t *bytes, z_owned_slice_t *dst); +z_result_t z_bytes_to_slice(const z_loaned_bytes_t *bytes, z_owned_slice_t *dst); /** - * Decodes data into a :c:type:`z_owned_string_t` + * Converts data into a :c:type:`z_owned_string_t` * * Parameters: * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. @@ -649,296 +529,136 @@ z_result_t z_bytes_deserialize_into_slice(const z_loaned_bytes_t *bytes, z_owned * Return: * ``0`` if decode successful, or a ``negative value`` otherwise. */ -z_result_t z_bytes_deserialize_into_string(const z_loaned_bytes_t *bytes, z_owned_string_t *str); - -/** - * Decodes data into a pair of :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to decode. - * first: Pointer to an uninitialized :c:type:`z_owned_bytes_t` to contain the first element. - * second: Pointer to an uninitialized :c:type:`z_owned_bytes_t` to contain the second element. - * - * Return: - * ``0`` if decode successful, or a ``negative value`` otherwise. - */ -z_result_t z_bytes_deserialize_into_pair(const z_loaned_bytes_t *bytes, z_owned_bytes_t *first, - z_owned_bytes_t *second); - -/** - * Encodes a signed integer into a :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded int. - * val: `int8_t` value to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_int8(z_owned_bytes_t *bytes, int8_t val); +z_result_t z_bytes_to_string(const z_loaned_bytes_t *bytes, z_owned_string_t *str); /** - * Encodes a signed integer into a :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded int. - * val: `int16_t` value to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_int16(z_owned_bytes_t *bytes, int16_t val); - -/** - * Encodes a signed integer into a :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded int. - * val: `int32_t` value to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_int32(z_owned_bytes_t *bytes, int32_t val); - -/** - * Encodes a signed integer into a :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded int. - * val: `int64_t` value to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_int64(z_owned_bytes_t *bytes, int64_t val); - -/** - * Encodes an unsigned integer into a :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded int. - * val: `uint8_t` value to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_uint8(z_owned_bytes_t *bytes, uint8_t val); - -/** - * Encodes an unsigned integer into a :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded int. - * val: `uint16_t` value to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_uint16(z_owned_bytes_t *bytes, uint16_t val); - -/** - * Encodes an unsigned integer into a :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded int. - * val: `uint32_t` value to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_uint32(z_owned_bytes_t *bytes, uint32_t val); - -/** - * Encodes an unsigned integer into a :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded int. - * val: `uint64_t` value to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_uint64(z_owned_bytes_t *bytes, uint64_t val); - -/** - * Encodes a floating number into a :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded int. - * val: `float` value to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_float(z_owned_bytes_t *bytes, float val); - -/** - * Encodes a floating number into a :c:type:`z_owned_bytes_t` - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded int. - * val: `double` value to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_double(z_owned_bytes_t *bytes, double val); - -/** - * Encodes a slice into a :c:type:`z_owned_bytes_t` by copying. + * Converts a slice into a :c:type:`z_owned_bytes_t`. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded slice. - * slice: Pointer to the slice to encode. + * slice: Pointer to the slice to convert. The slice will be consumed upon function return. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` if conversion is successful, ``negative value`` otherwise. */ -z_result_t z_bytes_serialize_from_slice(z_owned_bytes_t *bytes, const z_loaned_slice_t *slice); +z_result_t z_bytes_from_slice(z_owned_bytes_t *bytes, z_moved_slice_t *slice); /** - * Encodes a slice into a :c:type:`z_owned_bytes_t`. + * Converts a slice into a :c:type:`z_owned_bytes_t` by copying. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded slice. - * slice: Pointer to the slice to encode. The slice will be consumed upon function return. + * slice: Pointer to the slice to convert. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` if conversion is successful, ``negative value`` otherwise. */ -z_result_t z_bytes_from_slice(z_owned_bytes_t *bytes, z_moved_slice_t *slice); +z_result_t z_bytes_copy_from_slice(z_owned_bytes_t *bytes, const z_loaned_slice_t *slice); /** - * Encodes data into a :c:type:`z_owned_bytes_t`. + * Converts data into a :c:type:`z_owned_bytes_t`. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded data. - * data: Pointer to the data to encode. Ownership is transferred to the `bytes`. - * len: Number of bytes to encode. + * data: Pointer to the data to convert. Ownership is transferred to the `bytes`. + * len: Number of bytes to consider. * deleter: A thread-safe delete function to free the `data`. Will be called once when `bytes` is dropped. Can be * NULL, in case if `data` is allocated in static memory. * context: An optional context to be passed to the `deleter`. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` if conversion is successful, ``negative value`` otherwise. */ z_result_t z_bytes_from_buf(z_owned_bytes_t *bytes, uint8_t *data, size_t len, void (*deleter)(void *data, void *context), void *context); /** - * Encodes statically allocated constant data into a :c:type:`z_owned_bytes_t` by aliasing. + * Converts data into a :c:type:`z_owned_bytes_t` by copying. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded data. - * data: Pointer to the statically allocated constant data to encode. - * len: Number of bytes to encode. + * data: Pointer to the data to convert. + * len: Number of bytes to consider. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` if conversion is successful, ``negative value`` otherwise. */ -z_result_t z_bytes_from_static_buf(z_owned_bytes_t *bytes, const uint8_t *data, size_t len); +z_result_t z_bytes_copy_from_buf(z_owned_bytes_t *bytes, const uint8_t *data, size_t len); /** - * Encodes data into a :c:type:`z_owned_bytes_t` by copying. + * Converts statically allocated constant data into a :c:type:`z_owned_bytes_t` by aliasing. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded data. - * data: Pointer to the data to encode. Ownership is transferred to the `bytes`. - * len: Number of bytes to encode. + * data: Pointer to the statically allocated constant data to encode. + * len: Number of bytes to consider. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` if conversion is successful, ``negative value`` otherwise. */ -z_result_t z_bytes_serialize_from_buf(z_owned_bytes_t *bytes, const uint8_t *data, size_t len); +z_result_t z_bytes_from_static_buf(z_owned_bytes_t *bytes, const uint8_t *data, size_t len); /** - * Encodes a string into a :c:type:`z_owned_bytes_t` by copying. + * Converts a string into a :c:type:`z_owned_bytes_t`. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded string. - * s: Pointer to the string to encode. + * s: Pointer to the string to convert. The string will be consumed upon function return. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` if conversion is successful, ``negative value`` otherwise. */ -z_result_t z_bytes_serialize_from_string(z_owned_bytes_t *bytes, const z_loaned_string_t *s); +z_result_t z_bytes_from_string(z_owned_bytes_t *bytes, z_moved_string_t *s); /** - * Encodes a string into a :c:type:`z_owned_bytes_t`. + * Converts a string into a :c:type:`z_owned_bytes_t` by copying. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded string. - * s: Pointer to the string to encode. The string will be consumed upon function return. + * s: Pointer to the string to convert. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` if conversion is successful, ``negative value`` otherwise. */ -z_result_t z_bytes_from_string(z_owned_bytes_t *bytes, z_moved_string_t *s); +z_result_t z_bytes_copy_from_string(z_owned_bytes_t *bytes, const z_loaned_string_t *s); /** - * Encodes a null-terminated string into a :c:type:`z_owned_bytes_t`. + * Converts a null-terminated string into a :c:type:`z_owned_bytes_t`. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded string. - * value: Pointer to the string to encode. Ownership is transferred to the `bytes`. + * value: Pointer to the string to converts. Ownership is transferred to the `bytes`. * deleter: A thread-safe delete function to free the `value`. Will be called once when `bytes` is dropped. Can be * NULL, in case if `value` is allocated in static memory. context: An optional context to be passed to the `deleter`. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` if conversion is successful, ``negative value`` otherwise. */ z_result_t z_bytes_from_str(z_owned_bytes_t *bytes, char *value, void (*deleter)(void *value, void *context), void *context); /** - * Encodes a statically allocated constant null-terminated string into a :c:type:`z_owned_bytes_t` by aliasing. + * Converts a null-terminated string into a :c:type:`z_owned_bytes_t` by copying. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded string. - * value: Pointer to the statically allocated constant string to encode. + * value: Pointer to the string to converts. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` if conversion is successful, ``negative value`` otherwise. */ -z_result_t z_bytes_from_static_str(z_owned_bytes_t *bytes, const char *value); +z_result_t z_bytes_copy_from_str(z_owned_bytes_t *bytes, const char *value); /** - * Encodes a null-terminated string into a :c:type:`z_owned_bytes_t` by copying. + * Converts a statically allocated constant null-terminated string into a :c:type:`z_owned_bytes_t` by aliasing. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded string. - * value: Pointer to the string to encode. Ownership is transferred to the `bytes`. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_serialize_from_str(z_owned_bytes_t *bytes, const char *value); - -/** - * Constructs payload from an iterator to `z_owned_bytes_t`. - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded payload. - * iterator_body: Iterator body function, providing data items. Returning false is treated as iteration end. - * context: Arbitrary context that will be passed to iterator_body. + * value: Pointer to the statically allocated constant string to convert. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` if conversion is successful, ``negative value`` otherwise. */ -z_result_t z_bytes_from_iter(z_owned_bytes_t *bytes, bool (*iterator_body)(z_owned_bytes_t *data, void *context), - void *context); - -/** - * Append a pair of `z_owned_bytes` objects which are consumed in the process. - * - * Parameters: - * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the encoded pair. - * first: Moved first `z_owned_bytes` to encode. - * second: Moved second `z_owned_bytes` to encode. - * - * Return: - * ``0`` if encode successful, ``negative value`` otherwise. - */ -z_result_t z_bytes_from_pair(z_owned_bytes_t *bytes, z_moved_bytes_t *first, z_moved_bytes_t *second); +z_result_t z_bytes_from_static_str(z_owned_bytes_t *bytes, const char *value); /** * Parameters: @@ -966,30 +686,6 @@ size_t z_bytes_len(const z_loaned_bytes_t *bytes); */ bool z_bytes_is_empty(const z_loaned_bytes_t *bytes); -/** - * Returns an iterator for multi-element serialized data. - * - * Parameters: - * bytes: Data to iterate over. - * - * Return: - * The constructed :c:type:`z_bytes_iterator_t`. - */ -z_bytes_iterator_t z_bytes_get_iterator(const z_loaned_bytes_t *bytes); - -/** - * Constructs :c:type:`z_owned_bytes_t` object corresponding to the next element of serialized data. - * - * Will construct null-state `z_owned_bytes_t` when iterator reaches the end (or in case of error). - * - * Parameters: - * iter: An iterator over multi-element serialized data. - * 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`. * @@ -1031,19 +727,6 @@ bool z_bytes_slice_iterator_next(z_bytes_slice_iterator_t *iter, z_view_slice_t */ z_bytes_reader_t z_bytes_get_reader(const z_loaned_bytes_t *bytes); -/** - * Reads data into specified destination. - * - * Parameters: - * reader: Data reader to read from. - * dst: An uninitialized memory location where a new piece of data will be read. Note that it does not involve a copy, - * but only increases reference count. - * - * Return: - * ​0​ upon success, negative error code otherwise. - */ -z_result_t z_bytes_reader_read_bounded(z_bytes_reader_t *reader, z_owned_bytes_t *dst); - /** * Reads data into specified destination. * @@ -1083,46 +766,53 @@ z_result_t z_bytes_reader_seek(z_bytes_reader_t *reader, int64_t offset, int ori int64_t z_bytes_reader_tell(z_bytes_reader_t *reader); /** - * Constructs writer for :c:type:`z_loaned_bytes_t`. - * Note: creating another writer while previous one is still in use is undefined behaviour. + * Gets number of bytes that can still be read. * * Parameters: - * bytes: Data container to write to. - * writer: Uninitialized memory location where writer is to be constructed. + * reader: Data reader. * + * Return: + * Number of bytes that can still be read. */ -z_bytes_writer_t z_bytes_get_writer(z_loaned_bytes_t *bytes); +size_t z_bytes_reader_remaining(const z_bytes_reader_t *reader); /** - * Writes `len` bytes from `src` into underlying :c:type:`z_loaned_bytes_t. + * Constructs an empty writer for payload. * * Parameters: - * writer: A data writer. - * src: Buffer to write from. - * len: Number of bytes to write. + * writer: An uninitialized memory location where writer is to be constructed. * * Return: - * ``0`` if encode successful, ``negative value`` otherwise. + * ``0`` in case of success, ``negative value`` otherwise. */ -z_result_t z_bytes_writer_write_all(z_bytes_writer_t *writer, const uint8_t *src, size_t len); +z_result_t z_bytes_writer_empty(z_owned_bytes_writer_t *writer); /** - * Appends bytes. - * This allows to compose a serialized data out of multiple `z_owned_bytes_t` that may point to different memory - * regions. Said in other terms, it allows to create a linear view on different memory regions without copy. + * Finishes writing and returns underlying bytes. * * Parameters: * writer: A data writer. - * bytes: A data to append. + * bytes: An uninitialized memory location where bytes is to be constructed. + * + */ +void z_bytes_writer_finish(z_moved_bytes_writer_t *writer, z_owned_bytes_t *bytes); +/** + * Writes `len` bytes from `src` into underlying :c:type:`z_loaned_bytes_t. + * + * Parameters: + * writer: A data writer. + * src: Buffer to write from. + * len: Number of bytes to write. * * Return: - * 0 in case of success, negative error code otherwise + * ``0`` if write is successful, ``negative value`` otherwise. */ -z_result_t z_bytes_writer_append(z_bytes_writer_t *writer, z_moved_bytes_t *bytes); +z_result_t z_bytes_writer_write_all(z_loaned_bytes_writer_t *writer, const uint8_t *src, size_t len); /** - * Appends bytes, with boundaries information. It would allow to read the same piece of data using - * :c:func:`z_bytes_reader_read_bounded`. + * Appends bytes. + * This allows to compose a serialized data out of multiple `z_owned_bytes_t` that may point to different memory + * regions. Said in other terms, it allows to create a linear view on different memory regions without copy. * * Parameters: * writer: A data writer. @@ -1131,7 +821,7 @@ z_result_t z_bytes_writer_append(z_bytes_writer_t *writer, z_moved_bytes_t *byte * Return: * 0 in case of success, negative error code otherwise */ -z_result_t z_bytes_writer_append_bounded(z_bytes_writer_t *writer, z_moved_bytes_t *bytes); +z_result_t z_bytes_writer_append(z_loaned_bytes_writer_t *writer, z_moved_bytes_t *bytes); /** * Create timestamp. @@ -1367,6 +1057,7 @@ _Z_OWNED_FUNCTIONS_DEF(sample) _Z_OWNED_FUNCTIONS_DEF(query) _Z_OWNED_FUNCTIONS_DEF(slice) _Z_OWNED_FUNCTIONS_DEF(bytes) +_Z_OWNED_FUNCTIONS_NO_COPY_DEF(bytes_writer) _Z_OWNED_FUNCTIONS_DEF(reply_err) _Z_OWNED_FUNCTIONS_DEF(encoding) diff --git a/include/zenoh-pico/api/serialization.h b/include/zenoh-pico/api/serialization.h new file mode 100644 index 000000000..4bc214860 --- /dev/null +++ b/include/zenoh-pico/api/serialization.h @@ -0,0 +1,809 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +#ifndef INCLUDE_ZENOH_PICO_API_SERIALIZATION_H +#define INCLUDE_ZENOH_PICO_API_SERIALIZATION_H + +#include "olv_macros.h" +#include "zenoh-pico/api/primitives.h" +#include "zenoh-pico/utils/endianness.h" + +#if defined(Z_FEATURE_UNSTABLE_API) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Represents a reader for serialized data (unstable). + */ +typedef struct ze_deserializer_t { + z_bytes_reader_t _reader; +} ze_deserializer_t; + +typedef struct _ze_serializer_t { + _z_bytes_writer_t _writer; +} _ze_serializer_t; + +/** + * Represents a writer for serialized data (unstable). + */ +_Z_OWNED_TYPE_VALUE_PREFIX(ze, _ze_serializer_t, serializer) + +/** + * Constructs an empty serializer (unstable). + * + * Parameters: + * serializer: An uninitialized memory location where serializer is to be constructed. + * + * Return: + * ``0`` in case of success, ``negative value`` otherwise. + */ +z_result_t ze_serializer_empty(ze_owned_serializer_t *serializer); + +/** + * Finishes serialization and returns underlying bytes (unstable). + * + * Parameters: + * serializer: A data serializer. + * bytes: An uninitialized memory location where bytes is to be constructed. + * + */ +void ze_serializer_finish(ze_moved_serializer_t *serializer, z_owned_bytes_t *bytes); + +/** + * Returns a deserializer for :c:type:`z_loaned_bytes_t` (unstable). + * + * The `bytes` should outlive the reader and should not be modified, while reader is in use. + * + * Parameters: + * bytes: Data to deserialize. + * + * Return: + * The constructed :c:type:`ze_deserializer_t`. + */ +ze_deserializer_t ze_deserializer_from_bytes(const z_loaned_bytes_t *bytes); + +/** + * Checks if deserializer parsed all of its data (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * + * Return: + * ``True`` if there is no more data to parse, ``false`` otherwise. + */ +bool ze_deserializer_is_done(const ze_deserializer_t *deserializer); + +/** + * Writes a serialized :c:type:`uint8_t` into underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: `uint8_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +static inline z_result_t ze_serializer_serialize_uint8(ze_loaned_serializer_t *serializer, uint8_t val) { + return z_bytes_writer_write_all(&serializer->_writer, &val, 1); +} + +/** + * Writes a serialized :c:type:`uint16_t` into underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: `uint16_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +static inline z_result_t ze_serializer_serialize_uint16(ze_loaned_serializer_t *serializer, uint16_t val) { + _z_host_le_store16(val, (uint8_t *)&val); + return z_bytes_writer_write_all(&serializer->_writer, (uint8_t *)&val, sizeof(val)); +} + +/** + * Writes a serialized :c:type:`uint32_t` into underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: `uint32_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +static inline z_result_t ze_serializer_serialize_uint32(ze_loaned_serializer_t *serializer, uint32_t val) { + _z_host_le_store32(val, (uint8_t *)&val); + return z_bytes_writer_write_all(&serializer->_writer, (uint8_t *)&val, sizeof(val)); +} + +/** + * Writes a serialized :c:type:`uint64_t` into underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: `uint64_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +static inline z_result_t ze_serializer_serialize_uint64(ze_loaned_serializer_t *serializer, uint64_t val) { + _z_host_le_store64(val, (uint8_t *)&val); + return z_bytes_writer_write_all(&serializer->_writer, (uint8_t *)&val, sizeof(val)); +} + +/** + * Writes a serialized :c:type:`float` into underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: `float` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +static inline z_result_t ze_serializer_serialize_float(ze_loaned_serializer_t *serializer, float val) { + return z_bytes_writer_write_all(&serializer->_writer, (uint8_t *)&val, sizeof(val)); +} + +/** + * Writes a serialized :c:type:`double` into underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: `double` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +static inline z_result_t ze_serializer_serialize_double(ze_loaned_serializer_t *serializer, double val) { + return z_bytes_writer_write_all(&serializer->_writer, (uint8_t *)&val, sizeof(val)); +} + +/** + * Writes a serialized :c:type:`int8_t` into underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: `int8_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +static inline z_result_t ze_serializer_serialize_int8(ze_loaned_serializer_t *serializer, int8_t val) { + return ze_serializer_serialize_uint8(serializer, (uint8_t)val); +} + +/** + * Writes a serialized :c:type:`int16_t` into underlying :c:type:`z_owned_bytes_t`. + * + * Parameters: + * serializer: A serializer instance. + * val: `int16_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +static inline z_result_t ze_serializer_serialize_int16(ze_loaned_serializer_t *serializer, int16_t val) { + return ze_serializer_serialize_uint16(serializer, (uint16_t)val); +} + +/** + * Writes a serialized :c:type:`int32_t` into underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: `int32_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +static inline z_result_t ze_serializer_serialize_int32(ze_loaned_serializer_t *serializer, int32_t val) { + return ze_serializer_serialize_uint32(serializer, (uint32_t)val); +} + +/** + * Writes a serialized :c:type:`int64_t` into underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: `int64_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +static inline z_result_t ze_serializer_serialize_int64(ze_loaned_serializer_t *serializer, int64_t val) { + return ze_serializer_serialize_uint64(serializer, (uint64_t)val); +} + +/** + * Deserializes next portion of data into a `uint8_t` (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * dst: Pointer to an uninitialized :c:type:`uint8_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +static inline z_result_t ze_deserializer_deserialize_uint8(ze_deserializer_t *deserializer, uint8_t *val) { + return z_bytes_reader_read(&deserializer->_reader, val, 1) == 1 ? _Z_RES_OK : _Z_ERR_DID_NOT_READ; +} + +/** + * Deserializes next portion of data into a `uint16_t` (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * dst: Pointer to an uninitialized :c:type:`uint16_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +static inline z_result_t ze_deserializer_deserialize_uint16(ze_deserializer_t *deserializer, uint16_t *val) { + if (z_bytes_reader_read(&deserializer->_reader, (uint8_t *)val, sizeof(uint16_t)) != sizeof(uint16_t)) { + return _Z_ERR_DID_NOT_READ; + } + *val = _z_host_le_load16((const uint8_t *)val); + return _Z_RES_OK; +} + +/** + * Deserializes next portion of data into a `uint32_t` (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * dst: Pointer to an uninitialized :c:type:`uint32_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +static inline z_result_t ze_deserializer_deserialize_uint32(ze_deserializer_t *deserializer, uint32_t *val) { + if (z_bytes_reader_read(&deserializer->_reader, (uint8_t *)val, sizeof(uint32_t)) != sizeof(uint32_t)) { + return _Z_ERR_DID_NOT_READ; + } + *val = _z_host_le_load32((uint8_t *)val); + return _Z_RES_OK; +} + +/** + * Deserializes next portion of data into a `uint64_t` (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * dst: Pointer to an uninitialized :c:type:`uint64_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +static inline z_result_t ze_deserializer_deserialize_uint64(ze_deserializer_t *deserializer, uint64_t *val) { + if (z_bytes_reader_read(&deserializer->_reader, (uint8_t *)val, sizeof(uint64_t)) != sizeof(uint64_t)) { + return _Z_ERR_DID_NOT_READ; + } + *val = _z_host_le_load64((uint8_t *)val); + return _Z_RES_OK; +} + +/** + * Deserializes next portion of data into a `float` (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * dst: Pointer to an uninitialized :c:type:`float` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +static inline z_result_t ze_deserializer_deserialize_float(ze_deserializer_t *deserializer, float *val) { + if (z_bytes_reader_read(&deserializer->_reader, (uint8_t *)val, sizeof(float)) != sizeof(float)) { + return _Z_ERR_DID_NOT_READ; + } + return _Z_RES_OK; +} + +/** + * Deserializes next portion of data into a `double` (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * dst: Pointer to an uninitialized :c:type:`double` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +static inline z_result_t ze_deserializer_deserialize_double(ze_deserializer_t *deserializer, double *val) { + if (z_bytes_reader_read(&deserializer->_reader, (uint8_t *)val, sizeof(double)) != sizeof(double)) { + return _Z_ERR_DID_NOT_READ; + } + return _Z_RES_OK; +} + +/** + * Deserializes next portion of data into a `int8_t` (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * dst: Pointer to an uninitialized :c:type:`int8_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +static inline z_result_t ze_deserializer_deserialize_int8(ze_deserializer_t *deserializer, int8_t *val) { + return ze_deserializer_deserialize_uint8(deserializer, (uint8_t *)val); +} + +/** + * Deserializes next portion of data into a `int16_t` (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * dst: Pointer to an uninitialized :c:type:`int16_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +static inline z_result_t ze_deserializer_deserialize_int16(ze_deserializer_t *deserializer, int16_t *val) { + return ze_deserializer_deserialize_uint16(deserializer, (uint16_t *)val); +} + +/** + * Deserializes next portion of data into a `int32_t` (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * dst: Pointer to an uninitialized :c:type:`int32_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +static inline z_result_t ze_deserializer_deserialize_int32(ze_deserializer_t *deserializer, int32_t *val) { + return ze_deserializer_deserialize_uint32(deserializer, (uint32_t *)val); +} + +/** + * Deserializes next portion of data into a `int64_t` (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * dst: Pointer to an uninitialized :c:type:`int64_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +static inline z_result_t ze_deserializer_deserialize_int64(ze_deserializer_t *deserializer, int64_t *val) { + return ze_deserializer_deserialize_uint64(deserializer, (uint64_t *)val); +} + +/** + * Serializes array of bytes and writes it into an underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: Pointer to the data to serialize. + * len: Number of bytes to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serializer_serialize_buf(ze_loaned_serializer_t *serializer, const uint8_t *val, size_t len); + +/** + * Serializes slice and writes it into an underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: A slice to serialize. + * len: Number of bytes to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serializer_serialize_slice(ze_loaned_serializer_t *serializer, const z_loaned_slice_t *val); + +/** + * Deserializes next portion of data and advances the reader position (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * val: Pointer to an uninitialized :c:type:`z_owned_slice_t` to contain the deserialized slice. + * + * Return: + * ``0`` if deserialization is successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserializer_deserialize_slice(ze_deserializer_t *deserializer, z_owned_slice_t *val); + +/** + * Serializes a null-terminated string and writes it into an underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: Pointer to the string to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serializer_serialize_str(ze_loaned_serializer_t *serializer, const char *val); + +/** + * Serializes a string and writes it into an underlying :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * serializer: A serializer instance. + * val: Pointer to the string to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serializer_serialize_string(ze_loaned_serializer_t *serializer, const z_loaned_string_t *val); + +/** + * Deserializes next portion of data and advances the reader position (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * val: Pointer to an uninitialized :c:type:`z_owned_string_t` to contain the deserialized string. + * + * Return: + * ``0`` if deserialization is successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserializer_deserialize_string(ze_deserializer_t *deserializer, z_owned_string_t *val); + +/** + * Initiate serialization of a sequence of multiple elements (unstable). + * + * Parameters: + * serializer: A serializer instance. + * len: Length of the sequence. Could be read during deserialization using + * :c:func:`ze_deserializer_deserialize_sequence_length`. + * + * Return: + * ``0`` if deserialization is successful, or a ``negative value`` otherwise. + */ +z_result_t ze_serializer_serialize_sequence_length(ze_loaned_serializer_t *serializer, size_t len); + +/** + * Initiate deserialization of a sequence of multiple elements (unstable). + * + * Parameters: + * deserializer: A deserializer instance. + * len: A pointer where the length of the sequence (previously passed via + * :c:func:`ze_serializer_serialize_sequence_length`) will be written. + * + * Return: + * ``0`` if deserialization is successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserializer_deserialize_sequence_length(ze_deserializer_t *deserializer, size_t *len); + +/** + * Serializes data into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized data. + * data: Pointer to the data to serialize. Ownership is transferred to the `bytes`. + * len: Number of bytes to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_buf(z_owned_bytes_t *bytes, const uint8_t *data, size_t len); + +/** + * Serializes a string into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized string. + * s: Pointer to the string to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_string(z_owned_bytes_t *bytes, const z_loaned_string_t *s); + +/** + * Serializes a null-terminated string into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized string. + * value: Pointer to the string to serialize. Ownership is transferred to the `bytes`. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_str(z_owned_bytes_t *bytes, const char *value); + +/** + * Serializes a slice into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized slice. + * slice: Pointer to the slice to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_slice(z_owned_bytes_t *bytes, const z_loaned_slice_t *slice); + +/** + * Serializes a :c:type:`int8_t` into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized int. + * val: `int8_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_int8(z_owned_bytes_t *bytes, int8_t val); + +/** + * Serializes a :c:type:`int16_t` into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized int. + * val: `int16_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_int16(z_owned_bytes_t *bytes, int16_t val); + +/** + * Serializes a :c:type:`int32_t` into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized int. + * val: `int32_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_int32(z_owned_bytes_t *bytes, int32_t val); + +/** + * Serializes a :c:type:`int64_t` into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized int. + * val: `int64_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_int64(z_owned_bytes_t *bytes, int64_t val); + +/** + * Serializes a :c:type:`uint8_t` into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized int. + * val: `uint8_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_uint8(z_owned_bytes_t *bytes, uint8_t val); + +/** + * Serializes a :c:type:`uint16_t` into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized int. + * val: `uint16_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_uint16(z_owned_bytes_t *bytes, uint16_t val); + +/** + * Serializes a :c:type:`uint32_t` into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized int. + * val: `uint32_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_uint32(z_owned_bytes_t *bytes, uint32_t val); + +/** + * Serializes a :c:type:`uint64_t` into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized int. + * val: `uint64_t` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_uint64(z_owned_bytes_t *bytes, uint64_t val); + +/** + * Serializes a :c:type:`float` into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized int. + * val: `float` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_float(z_owned_bytes_t *bytes, float val); + +/** + * Serializes a :c:type:`double` into a :c:type:`z_owned_bytes_t` (unstable). + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized int. + * val: `double` value to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_double(z_owned_bytes_t *bytes, double val); + +/** + * Deserializes data into a :c:type:`z_owned_slice_t` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * str: Pointer to an uninitialized :c:type:`z_owned_slice_t` to contain the deserialized slice. + * + * Return: + * ``0`` if deserialization is successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_slice(const z_loaned_bytes_t *bytes, z_owned_slice_t *dst); + +/** + * Deserializes data into a :c:type:`z_owned_string_t` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * str: Pointer to an uninitialized :c:type:`z_owned_string_t` to contain the deserialized string. + * + * Return: + * ``0`` if deserialization is successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_string(const z_loaned_bytes_t *bytes, z_owned_string_t *str); + +/** + * Deserializes data into a `:c:type:`int8_t` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * dst: Pointer to an uninitialized :c:type:`int8_t` to contain the deserialized. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_int8(const z_loaned_bytes_t *bytes, int8_t *dst); + +/** + * Deserializes data into a :c:type:`int16_t` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * dst: Pointer to an uninitialized :c:type:`int16_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_int16(const z_loaned_bytes_t *bytes, int16_t *dst); + +/** + * Deserializes data into a :c:type:`int32_t` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * dst: Pointer to an uninitialized :c:type:`int32_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_int32(const z_loaned_bytes_t *bytes, int32_t *dst); + +/** + * Deserializes data into a :c:type:`int64_t` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * dst: Pointer to an uninitialized :c:type:`int64_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_int64(const z_loaned_bytes_t *bytes, int64_t *dst); + +/** + * Deserializes data into a :c:type:`uint8_t` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * dst: Pointer to an uninitialized :c:type:`uint8_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_uint8(const z_loaned_bytes_t *bytes, uint8_t *dst); + +/** + * Deserializes data into a :c:type:`uint16_t` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * dst: Pointer to an uninitialized :c:type:`uint16_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_uint16(const z_loaned_bytes_t *bytes, uint16_t *dst); + +/** + * Deserializes data into a :c:type:`uint32_t` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * dst: Pointer to an uninitialized :c:type:`uint32_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_uint32(const z_loaned_bytes_t *bytes, uint32_t *dst); + +/** + * Deserializes data into a `:c:type:`uint64_t` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * dst: Pointer to an uninitialized :c:type:`uint64_t` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_uint64(const z_loaned_bytes_t *bytes, uint64_t *dst); + +/** + * Deserializes data into a `:c:type:`float` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * dst: Pointer to an uninitialized :c:type:`float` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_float(const z_loaned_bytes_t *bytes, float *dst); + +/** + * Deserializes data into a :c:type:`double` (unstable). + * + * Parameters: + * bytes: Pointer to a :c:type:`z_loaned_bytes_t` to deserialize. + * dst: Pointer to an uninitialized :c:type:`double` to contain the deserialized number. + * + * Return: + * ``0`` if deserialization successful, or a ``negative value`` otherwise. + */ +z_result_t ze_deserialize_double(const z_loaned_bytes_t *bytes, double *dst); + +_Z_OWNED_FUNCTIONS_NO_COPY_DEF_PREFIX(ze, serializer) +#ifdef __cplusplus +} +#endif + +#endif +#endif diff --git a/include/zenoh-pico/api/types.h b/include/zenoh-pico/api/types.h index e7a325f36..2e42bcbb4 100644 --- a/include/zenoh-pico/api/types.h +++ b/include/zenoh-pico/api/types.h @@ -72,22 +72,17 @@ _Z_VIEW_TYPE(_z_slice_t, slice) _Z_OWNED_TYPE_VALUE(_z_bytes_t, bytes) /** - * Represents a writer for serialized data. + * Represents a writer for data. */ -typedef _z_bytes_iterator_writer_t z_bytes_writer_t; +_Z_OWNED_TYPE_VALUE(_z_bytes_writer_t, bytes_writer) /** - * An iterator over multi-element serialized data. + * A reader for data. */ -typedef _z_bytes_iterator_t z_bytes_iterator_t; +typedef _z_bytes_reader_t z_bytes_reader_t; /** - * A reader for serialized data. - */ -typedef _z_bytes_iterator_t z_bytes_reader_t; - -/** - * An iterator over slices of serialized data. + * An iterator over slices of data. */ typedef struct { const _z_bytes_t *_bytes; diff --git a/include/zenoh-pico/collections/bytes.h b/include/zenoh-pico/collections/bytes.h index 99e70f178..b662ff613 100644 --- a/include/zenoh-pico/collections/bytes.h +++ b/include/zenoh-pico/collections/bytes.h @@ -58,24 +58,10 @@ size_t _z_bytes_num_slices(const _z_bytes_t *bs); _z_arc_slice_t *_z_bytes_get_slice(const _z_bytes_t *bs, size_t i); size_t _z_bytes_len(const _z_bytes_t *bs); bool _z_bytes_is_empty(const _z_bytes_t *bs); -z_result_t _z_bytes_to_uint8(const _z_bytes_t *bs, uint8_t *u); -z_result_t _z_bytes_to_uint16(const _z_bytes_t *bs, uint16_t *u); -z_result_t _z_bytes_to_uint32(const _z_bytes_t *bs, uint32_t *u); -z_result_t _z_bytes_to_uint64(const _z_bytes_t *bs, uint64_t *u); -z_result_t _z_bytes_to_float(const _z_bytes_t *bs, float *f); -z_result_t _z_bytes_to_double(const _z_bytes_t *bs, double *d); z_result_t _z_bytes_to_slice(const _z_bytes_t *bytes, _z_slice_t *s); z_result_t _z_bytes_from_slice(_z_bytes_t *b, _z_slice_t s); -z_result_t _z_bytes_from_uint8(_z_bytes_t *b, uint8_t val); -z_result_t _z_bytes_from_uint16(_z_bytes_t *b, uint16_t val); -z_result_t _z_bytes_from_uint32(_z_bytes_t *b, uint32_t val); -z_result_t _z_bytes_from_uint64(_z_bytes_t *b, uint64_t val); -z_result_t _z_bytes_from_float(_z_bytes_t *b, float val); -z_result_t _z_bytes_from_double(_z_bytes_t *b, double val); size_t _z_bytes_to_buf(const _z_bytes_t *bytes, uint8_t *dst, size_t len); z_result_t _z_bytes_from_buf(_z_bytes_t *b, const uint8_t *src, size_t len); -z_result_t _z_bytes_from_pair(_z_bytes_t *out, _z_bytes_t *first, _z_bytes_t *second); -z_result_t _z_bytes_deserialize_into_pair(const _z_bytes_t *bs, _z_bytes_t *first_out, _z_bytes_t *second_out); _z_slice_t _z_bytes_try_get_contiguous(const _z_bytes_t *bs); typedef struct { @@ -92,27 +78,20 @@ z_result_t _z_bytes_reader_read_slices(_z_bytes_reader_t *reader, size_t len, _z size_t _z_bytes_reader_read(_z_bytes_reader_t *reader, uint8_t *buf, size_t len); typedef struct { - _z_bytes_reader_t _reader; -} _z_bytes_iterator_t; - -_z_bytes_iterator_t _z_bytes_get_iterator(const _z_bytes_t *bytes); -z_result_t _z_bytes_iterator_next(_z_bytes_iterator_t *iter, _z_bytes_t *b); - -typedef struct { - uint8_t *cache; - size_t cache_size; - _z_bytes_t *bytes; + _z_arc_slice_t *cache; + _z_bytes_t bytes; } _z_bytes_writer_t; -_z_bytes_writer_t _z_bytes_get_writer(_z_bytes_t *bytes, size_t cache_size); +bool _z_bytes_writer_is_empty(const _z_bytes_writer_t *writer); +bool _z_bytes_writer_check(const _z_bytes_writer_t *writer); +_z_bytes_writer_t _z_bytes_writer_from_bytes(_z_bytes_t *bytes); +_z_bytes_writer_t _z_bytes_writer_empty(void); z_result_t _z_bytes_writer_write_all(_z_bytes_writer_t *writer, const uint8_t *src, size_t len); -z_result_t _z_bytes_writer_append(_z_bytes_writer_t *writer, _z_bytes_t *bytes); -z_result_t _z_bytes_writer_ensure_cache(_z_bytes_writer_t *writer); - -typedef struct { - _z_bytes_writer_t writer; -} _z_bytes_iterator_writer_t; +z_result_t _z_bytes_writer_append_z_bytes(_z_bytes_writer_t *writer, _z_bytes_t *bytes); +z_result_t _z_bytes_writer_append_slice(_z_bytes_writer_t *writer, _z_arc_slice_t *bytes); +_z_bytes_t _z_bytes_writer_finish(_z_bytes_writer_t *writer); +void _z_bytes_writer_clear(_z_bytes_writer_t *writer); +void _z_bytes_writer_move(_z_bytes_writer_t *dst, _z_bytes_writer_t *src); +size_t _z_bytes_reader_remaining(const _z_bytes_reader_t *reader); -_z_bytes_iterator_writer_t _z_bytes_get_iterator_writer(_z_bytes_t *bytes, size_t cache_size); -z_result_t _z_bytes_iterator_writer_write(_z_bytes_iterator_writer_t *writer, _z_bytes_t *bytes); #endif /* ZENOH_PICO_COLLECTIONS_BYTES_H */ diff --git a/include/zenoh-pico/utils/endianness.h b/include/zenoh-pico/utils/endianness.h index 5a29bbf93..90fc87af0 100644 --- a/include/zenoh-pico/utils/endianness.h +++ b/include/zenoh-pico/utils/endianness.h @@ -18,34 +18,140 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(ZENOH_ENDIANNNESS_BIG) && !defined(ZENOH_ENDIANNNESS_LITTLE) +// Gcc/clang test +#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define ZENOH_ENDIANNNESS_BIG +#else +#define ZENOH_ENDIANNNESS_LITTLE +#endif +#endif + // Load int from memory with specified endianness -uint16_t _z_le_load16(const uint8_t *src); -uint32_t _z_le_load32(const uint8_t *src); -uint64_t _z_le_load64(const uint8_t *src); -uint16_t _z_be_load16(const uint8_t *src); -uint32_t _z_be_load32(const uint8_t *src); -uint64_t _z_be_load64(const uint8_t *src); - -// Store int to memory with specified endianness -size_t _z_le_store16(uint16_t val, uint8_t *dest); -size_t _z_le_store32(uint32_t val, uint8_t *dest); -size_t _z_le_store64(uint64_t val, uint8_t *dest); -size_t _z_be_store16(uint16_t val, uint8_t *dest); -size_t _z_be_store32(uint32_t val, uint8_t *dest); -size_t _z_be_store64(uint64_t val, uint8_t *dest); - -// Load little-endian int from memory to host order -uint16_t _z_host_le_load16(const uint8_t *src); -uint32_t _z_host_le_load32(const uint8_t *src); -uint64_t _z_host_le_load64(const uint8_t *src); - -// Store little-endian int to memory from host order -size_t _z_host_le_store16(const uint16_t val, uint8_t *dst); -size_t _z_host_le_store32(const uint32_t val, uint8_t *dst); -size_t _z_host_le_store64(const uint64_t val, uint8_t *dst); + +// *** Little endian *** +#define _Z_LE_LOAD_IMPL(SIZE) \ + static inline uint##SIZE##_t _z_le_load##SIZE(const uint8_t *src) { \ + uint##SIZE##_t val = 0; \ + for (size_t i = sizeof(val); i != 0; --i) { \ + val = val << 8; \ + val = val | src[i - 1]; \ + } \ + return val; \ + } + +#define _Z_LE_STORE_IMPL(SIZE) \ + static inline void _z_le_store##SIZE(uint##SIZE##_t val, uint8_t *dst) { \ + for (size_t i = 0; i < sizeof(val); ++i) { \ + dst[i] = (uint8_t)val; \ + val = val >> 8; \ + } \ + } + +_Z_LE_LOAD_IMPL(16) +_Z_LE_LOAD_IMPL(32) +_Z_LE_LOAD_IMPL(64) + +_Z_LE_STORE_IMPL(16) +_Z_LE_STORE_IMPL(32) +_Z_LE_STORE_IMPL(64) + +#undef _Z_LE_LOAD_IMPL +#undef _Z_LE_STORE_IMPL + +// *** Big endian *** +#define _Z_BE_LOAD_IMPL(SIZE) \ + static inline uint##SIZE##_t _z_be_load##SIZE(const uint8_t *src) { \ + uint##SIZE##_t val = 0; \ + for (size_t i = 0; i < sizeof(val); ++i) { \ + val = val << 8; \ + val = val | src[i]; \ + } \ + return val; \ + } + +#define _Z_BE_STORE_IMPL(SIZE) \ + static inline void _z_be_store##SIZE(uint##SIZE##_t val, uint8_t *dst) { \ + for (size_t i = sizeof(val); i != 0; --i) { \ + dst[i - 1] = (uint8_t)val; \ + val = val >> 8; \ + } \ + } + +_Z_BE_LOAD_IMPL(16) +_Z_BE_LOAD_IMPL(32) +_Z_BE_LOAD_IMPL(64) + +_Z_BE_STORE_IMPL(16) +_Z_BE_STORE_IMPL(32) +_Z_BE_STORE_IMPL(64) + +#undef _Z_BE_LOAD_IMPL +#undef _Z_BE_STORE_IMPL + +// *** Host *** +static inline uint16_t _z_host_le_load8(const uint8_t *src) { return src[0]; } + +static inline uint16_t _z_host_le_load16(const uint8_t *src) { +#if defined(ZENOH_ENDIANNNESS_BIG) + return _z_be_load16(src); +#elif defined(ZENOH_ENDIANNNESS_LITTLE) + return _z_le_load16(src); +#endif +} + +static inline uint32_t _z_host_le_load32(const uint8_t *src) { +#if defined(ZENOH_ENDIANNNESS_BIG) + return _z_be_load32(src); +#elif defined(ZENOH_ENDIANNNESS_LITTLE) + return _z_le_load32(src); +#endif +} + +static inline uint64_t _z_host_le_load64(const uint8_t *src) { +#if defined(ZENOH_ENDIANNNESS_BIG) + return _z_be_load64(src); +#elif defined(ZENOH_ENDIANNNESS_LITTLE) + return _z_le_load64(src); +#endif +} + +static inline void _z_host_le_store8(const uint8_t val, uint8_t *dst) { dst[0] = val; } + +static inline void _z_host_le_store16(const uint16_t val, uint8_t *dst) { +#if defined(ZENOH_ENDIANNNESS_BIG) + _z_be_store16(val, dst); +#elif defined(ZENOH_ENDIANNNESS_LITTLE) + _z_le_store16(val, dst); +#endif +} + +static inline void _z_host_le_store32(const uint32_t val, uint8_t *dst) { +#if defined(ZENOH_ENDIANNNESS_BIG) + _z_be_store32(val, dst); +#elif defined(ZENOH_ENDIANNNESS_LITTLE) + _z_le_store32(val, dst); +#endif +} + +static inline void _z_host_le_store64(const uint64_t val, uint8_t *dst) { +#if defined(ZENOH_ENDIANNNESS_BIG) + _z_be_store64(val, dst); +#elif defined(ZENOH_ENDIANNNESS_LITTLE) + _z_le_store64(val, dst); +#endif +} // Return u16 individual bytes -uint8_t _z_get_u16_lsb(uint_fast16_t val); -uint8_t _z_get_u16_msb(uint_fast16_t val); +static inline uint8_t _z_get_u16_lsb(uint_fast16_t val) { return (uint8_t)(val >> 0); } +static inline uint8_t _z_get_u16_msb(uint_fast16_t val) { return (uint8_t)(val >> 8); } + +#ifdef __cplusplus +} +#endif #endif /* ZENOH_PICO_UTILS_ENDIANNESS_H */ diff --git a/include/zenoh-pico/utils/result.h b/include/zenoh-pico/utils/result.h index fd927598e..4dd16f141 100644 --- a/include/zenoh-pico/utils/result.h +++ b/include/zenoh-pico/utils/result.h @@ -81,6 +81,7 @@ typedef enum { Z_EINVAL = -75, _Z_ERR_OVERFLOW = -74, _Z_ERR_SESSION_CLOSED = -73, + Z_EDESERIALIZE = -72, _Z_ERR_GENERIC = -128 } _z_res_t; diff --git a/src/api/api.c b/src/api/api.c index c15929574..13cdb1b56 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -245,52 +245,12 @@ void z_slice_empty(z_owned_slice_t *slice) { slice->_val = _z_slice_empty(); } bool z_slice_is_empty(const z_loaned_slice_t *slice) { return _z_slice_is_empty(slice); } -z_result_t z_bytes_deserialize_into_int8(const z_loaned_bytes_t *bytes, int8_t *dst) { - return _z_bytes_to_uint8(bytes, (uint8_t *)dst); -} - -z_result_t z_bytes_deserialize_into_int16(const z_loaned_bytes_t *bytes, int16_t *dst) { - return _z_bytes_to_uint16(bytes, (uint16_t *)dst); -} - -z_result_t z_bytes_deserialize_into_int32(const z_loaned_bytes_t *bytes, int32_t *dst) { - return _z_bytes_to_uint32(bytes, (uint32_t *)dst); -} - -z_result_t z_bytes_deserialize_into_int64(const z_loaned_bytes_t *bytes, int64_t *dst) { - return _z_bytes_to_uint64(bytes, (uint64_t *)dst); -} - -z_result_t z_bytes_deserialize_into_uint8(const z_loaned_bytes_t *bytes, uint8_t *dst) { - return _z_bytes_to_uint8(bytes, dst); -} - -z_result_t z_bytes_deserialize_into_uint16(const z_loaned_bytes_t *bytes, uint16_t *dst) { - return _z_bytes_to_uint16(bytes, dst); -} - -z_result_t z_bytes_deserialize_into_uint32(const z_loaned_bytes_t *bytes, uint32_t *dst) { - return _z_bytes_to_uint32(bytes, dst); -} - -z_result_t z_bytes_deserialize_into_uint64(const z_loaned_bytes_t *bytes, uint64_t *dst) { - return _z_bytes_to_uint64(bytes, dst); -} - -z_result_t z_bytes_deserialize_into_float(const z_loaned_bytes_t *bytes, float *dst) { - return _z_bytes_to_float(bytes, dst); -} - -z_result_t z_bytes_deserialize_into_double(const z_loaned_bytes_t *bytes, double *dst) { - return _z_bytes_to_double(bytes, dst); -} - -z_result_t z_bytes_deserialize_into_slice(const z_loaned_bytes_t *bytes, z_owned_slice_t *dst) { +z_result_t z_bytes_to_slice(const z_loaned_bytes_t *bytes, z_owned_slice_t *dst) { dst->_val = _z_slice_empty(); return _z_bytes_to_slice(bytes, &dst->_val); } -z_result_t z_bytes_deserialize_into_string(const z_loaned_bytes_t *bytes, z_owned_string_t *s) { +z_result_t z_bytes_to_string(const z_loaned_bytes_t *bytes, z_owned_string_t *s) { // Init owned string z_internal_string_null(s); // Convert bytes to string @@ -301,60 +261,6 @@ z_result_t z_bytes_deserialize_into_string(const z_loaned_bytes_t *bytes, z_owne return _Z_RES_OK; } -z_result_t z_bytes_deserialize_into_pair(const z_loaned_bytes_t *bytes, z_owned_bytes_t *first, - z_owned_bytes_t *second) { - // Init pair of owned bytes - z_bytes_empty(first); - z_bytes_empty(second); - return _z_bytes_deserialize_into_pair(bytes, &first->_val, &second->_val); -} - -z_result_t z_bytes_serialize_from_int8(z_owned_bytes_t *bytes, int8_t val) { - return z_bytes_serialize_from_uint8(bytes, (uint8_t)val); -} - -z_result_t z_bytes_serialize_from_int16(z_owned_bytes_t *bytes, int16_t val) { - return z_bytes_serialize_from_uint16(bytes, (uint16_t)val); -} - -z_result_t z_bytes_serialize_from_int32(z_owned_bytes_t *bytes, int32_t val) { - return z_bytes_serialize_from_uint32(bytes, (uint32_t)val); -} - -z_result_t z_bytes_serialize_from_int64(z_owned_bytes_t *bytes, int64_t val) { - return z_bytes_serialize_from_uint64(bytes, (uint64_t)val); -} - -z_result_t z_bytes_serialize_from_uint8(z_owned_bytes_t *bytes, uint8_t val) { - z_bytes_empty(bytes); - return _z_bytes_from_uint8(&bytes->_val, val); -} - -z_result_t z_bytes_serialize_from_uint16(z_owned_bytes_t *bytes, uint16_t val) { - z_bytes_empty(bytes); - return _z_bytes_from_uint16(&bytes->_val, val); -} - -z_result_t z_bytes_serialize_from_uint32(z_owned_bytes_t *bytes, uint32_t val) { - z_bytes_empty(bytes); - return _z_bytes_from_uint32(&bytes->_val, val); -} - -z_result_t z_bytes_serialize_from_uint64(z_owned_bytes_t *bytes, uint64_t val) { - z_bytes_empty(bytes); - return _z_bytes_from_uint64(&bytes->_val, val); -} - -z_result_t z_bytes_serialize_from_float(z_owned_bytes_t *bytes, float val) { - z_bytes_empty(bytes); - return _z_bytes_from_float(&bytes->_val, val); -} - -z_result_t z_bytes_serialize_from_double(z_owned_bytes_t *bytes, double val) { - z_bytes_empty(bytes); - return _z_bytes_from_double(&bytes->_val, val); -} - z_result_t z_bytes_from_slice(z_owned_bytes_t *bytes, z_moved_slice_t *slice) { z_bytes_empty(bytes); _z_slice_t s = _z_slice_steal(&slice->_this._val); @@ -362,12 +268,6 @@ z_result_t z_bytes_from_slice(z_owned_bytes_t *bytes, z_moved_slice_t *slice) { return _Z_RES_OK; } -z_result_t z_bytes_serialize_from_slice(z_owned_bytes_t *bytes, const z_loaned_slice_t *slice) { - z_owned_slice_t s; - _Z_RETURN_IF_ERR(z_slice_clone(&s, slice)); - return z_bytes_from_slice(bytes, z_slice_move(&s)); -} - z_result_t z_bytes_from_buf(z_owned_bytes_t *bytes, uint8_t *data, size_t len, void (*deleter)(void *data, void *context), void *context) { z_owned_slice_t s; @@ -381,14 +281,20 @@ z_result_t z_bytes_from_static_buf(z_owned_bytes_t *bytes, const uint8_t *data, return z_bytes_from_slice(bytes, z_slice_move(&s)); } -z_result_t z_bytes_serialize_from_buf(z_owned_bytes_t *bytes, const uint8_t *data, size_t len) { +z_result_t z_bytes_copy_from_buf(z_owned_bytes_t *bytes, const uint8_t *data, size_t len) { z_owned_slice_t s; - _Z_RETURN_IF_ERR(z_slice_copy_from_buf(&s, data, len)); + s._val = _z_slice_copy_from_buf(data, len); + if (s._val.len != len) return _Z_ERR_SYSTEM_OUT_OF_MEMORY; + return z_bytes_from_slice(bytes, z_slice_move(&s)); +} + +z_result_t z_bytes_copy_from_slice(z_owned_bytes_t *bytes, const z_loaned_slice_t *slice) { + z_owned_slice_t s; + _Z_RETURN_IF_ERR(_z_slice_copy(&s._val, slice)); return z_bytes_from_slice(bytes, z_slice_move(&s)); } z_result_t z_bytes_from_string(z_owned_bytes_t *bytes, z_moved_string_t *s) { - // TODO, verify that string is a valid UTF-8 ? z_owned_slice_t slice; size_t str_len = _z_string_len(&s->_this._val); slice._val = _z_slice_steal(&s->_this._val._slice); @@ -396,10 +302,11 @@ z_result_t z_bytes_from_string(z_owned_bytes_t *bytes, z_moved_string_t *s) { return z_bytes_from_slice(bytes, z_slice_move(&slice)); } -z_result_t z_bytes_serialize_from_string(z_owned_bytes_t *bytes, const z_loaned_string_t *s) { - z_owned_string_t s_copy; - _Z_RETURN_IF_ERR(z_string_clone(&s_copy, s)); - return z_bytes_from_string(bytes, z_string_move(&s_copy)); +z_result_t z_bytes_copy_from_string(z_owned_bytes_t *bytes, const z_loaned_string_t *value) { + z_owned_string_t s; + _Z_RETURN_IF_ERR(_z_string_copy(&s._val, value)); + + return z_bytes_from_string(bytes, z_string_move(&s)); } z_result_t z_bytes_from_str(z_owned_bytes_t *bytes, char *value, void (*deleter)(void *value, void *context), @@ -409,67 +316,37 @@ z_result_t z_bytes_from_str(z_owned_bytes_t *bytes, char *value, void (*deleter) return z_bytes_from_string(bytes, z_string_move(&s)); } -z_result_t z_bytes_from_static_str(z_owned_bytes_t *bytes, const char *value) { +z_result_t z_bytes_copy_from_str(z_owned_bytes_t *bytes, const char *value) { z_owned_string_t s; - s._val = _z_string_alias_str(value); + s._val = _z_string_copy_from_str(value); + if (s._val._slice.start == NULL && value != NULL) return _Z_ERR_SYSTEM_OUT_OF_MEMORY; return z_bytes_from_string(bytes, z_string_move(&s)); } -z_result_t z_bytes_serialize_from_str(z_owned_bytes_t *bytes, const char *value) { +z_result_t z_bytes_from_static_str(z_owned_bytes_t *bytes, const char *value) { z_owned_string_t s; - _Z_RETURN_IF_ERR(z_string_copy_from_str(&s, value)); + s._val = _z_string_alias_str(value); return z_bytes_from_string(bytes, z_string_move(&s)); } -z_result_t z_bytes_from_iter(z_owned_bytes_t *bytes, bool (*iterator_body)(z_owned_bytes_t *data, void *context), - void *context) { - z_bytes_empty(bytes); - z_owned_bytes_t data; - _z_bytes_iterator_writer_t iter_writer = _z_bytes_get_iterator_writer(&bytes->_val, 0); - while (iterator_body(&data, context)) { - _Z_CLEAN_RETURN_IF_ERR(_z_bytes_iterator_writer_write(&iter_writer, &data._val), - z_bytes_drop(z_bytes_move(bytes))); - } - return _Z_RES_OK; -} - -z_result_t z_bytes_from_pair(z_owned_bytes_t *bytes, z_moved_bytes_t *first, z_moved_bytes_t *second) { - z_bytes_empty(bytes); - return _z_bytes_from_pair(&bytes->_val, &first->_this._val, &second->_this._val); -} - void z_bytes_empty(z_owned_bytes_t *bytes) { bytes->_val = _z_bytes_null(); } size_t z_bytes_len(const z_loaned_bytes_t *bytes) { return _z_bytes_len(bytes); } bool z_bytes_is_empty(const z_loaned_bytes_t *bytes) { return _z_bytes_is_empty(bytes); } -z_bytes_reader_t z_bytes_get_reader(const z_loaned_bytes_t *bytes) { return _z_bytes_get_iterator(bytes); } +z_bytes_reader_t z_bytes_get_reader(const z_loaned_bytes_t *bytes) { return _z_bytes_get_reader(bytes); } size_t z_bytes_reader_read(z_bytes_reader_t *reader, uint8_t *dst, size_t len) { - return _z_bytes_reader_read(&reader->_reader, dst, len); -} - -z_result_t z_bytes_reader_read_bounded(z_bytes_reader_t *reader, z_owned_bytes_t *dst) { - return _z_bytes_iterator_next(reader, &dst->_val); + return _z_bytes_reader_read(reader, dst, len); } z_result_t z_bytes_reader_seek(z_bytes_reader_t *reader, int64_t offset, int origin) { - return _z_bytes_reader_seek(&reader->_reader, offset, origin); + return _z_bytes_reader_seek(reader, offset, origin); } -int64_t z_bytes_reader_tell(z_bytes_reader_t *reader) { return _z_bytes_reader_tell(&reader->_reader); } - -z_bytes_iterator_t z_bytes_get_iterator(const z_loaned_bytes_t *bytes) { return _z_bytes_get_iterator(bytes); } - -bool z_bytes_iterator_next(z_bytes_iterator_t *iter, z_owned_bytes_t *bytes) { - z_bytes_empty(bytes); - if (_z_bytes_iterator_next(iter, &bytes->_val) != _Z_RES_OK) { - z_bytes_drop(z_bytes_move(bytes)); - return false; - } - return true; -} +int64_t z_bytes_reader_tell(z_bytes_reader_t *reader) { return _z_bytes_reader_tell(reader); } +size_t z_bytes_reader_remaining(const z_bytes_reader_t *reader) { return _z_bytes_reader_remaining(reader); } 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}; @@ -485,20 +362,21 @@ bool z_bytes_slice_iterator_next(z_bytes_slice_iterator_t *iter, z_view_slice_t 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); +void z_bytes_writer_finish(z_moved_bytes_writer_t *writer, z_owned_bytes_t *bytes) { + bytes->_val = _z_bytes_writer_finish(&writer->_this._val); } -z_result_t z_bytes_writer_write_all(z_bytes_writer_t *writer, const uint8_t *src, size_t len) { - return _z_bytes_writer_write_all(&writer->writer, src, len); +z_result_t z_bytes_writer_empty(z_owned_bytes_writer_t *writer) { + writer->_val = _z_bytes_writer_empty(); + return _Z_RES_OK; } -z_result_t z_bytes_writer_append(z_bytes_writer_t *writer, z_moved_bytes_t *bytes) { - return _z_bytes_writer_append(&writer->writer, &bytes->_this._val); +z_result_t z_bytes_writer_write_all(z_loaned_bytes_writer_t *writer, const uint8_t *src, size_t len) { + return _z_bytes_writer_write_all(writer, src, len); } -z_result_t z_bytes_writer_append_bounded(z_bytes_writer_t *writer, z_moved_bytes_t *bytes) { - return _z_bytes_iterator_writer_write(writer, &bytes->_this._val); +z_result_t z_bytes_writer_append(z_loaned_bytes_writer_t *writer, z_moved_bytes_t *bytes) { + return _z_bytes_writer_append_z_bytes(writer, &bytes->_this._val); } z_result_t z_timestamp_new(z_timestamp_t *ts, const z_loaned_session_t *zs) { @@ -644,6 +522,8 @@ _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_string_svec_t, string_array, _z_string_array_ch _z_string_array_copy, _z_string_svec_clear) _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_slice_t, slice, _z_slice_check, _z_slice_empty, _z_slice_copy, _z_slice_clear) _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_bytes_t, bytes, _z_bytes_check, _z_bytes_null, _z_bytes_copy, _z_bytes_drop) +_Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL(_z_bytes_writer_t, bytes_writer, _z_bytes_writer_check, _z_bytes_writer_empty, + _z_bytes_writer_clear) #if Z_FEATURE_PUBLICATION == 1 || Z_FEATURE_QUERYABLE == 1 || Z_FEATURE_QUERY == 1 // Convert a user owned bytes payload to an internal bytes payload, returning an empty one if value invalid diff --git a/src/api/serialization.c b/src/api/serialization.c new file mode 100644 index 000000000..96af3370e --- /dev/null +++ b/src/api/serialization.c @@ -0,0 +1,169 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, + +#include "zenoh-pico/api/serialization.h" + +#include + +#include "zenoh-pico/protocol/codec/core.h" + +#if defined(Z_FEATURE_UNSTABLE_API) +bool _ze_serializer_check(const _ze_serializer_t *serializer) { return _z_bytes_writer_check(&serializer->_writer); } + +_ze_serializer_t _ze_serializer_empty(void) { + _ze_serializer_t s; + s._writer = _z_bytes_writer_empty(); + return s; +} + +void _ze_serializer_clear(_ze_serializer_t *serializer) { _z_bytes_writer_clear(&serializer->_writer); } + +_Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL_PREFIX(ze, _ze_serializer_t, serializer, _ze_serializer_check, + _ze_serializer_empty, _ze_serializer_clear) + +z_result_t ze_serializer_empty(ze_owned_serializer_t *serializer) { + serializer->_val._writer = _z_bytes_writer_empty(); + return _Z_RES_OK; +} + +void ze_serializer_finish(ze_moved_serializer_t *serializer, z_owned_bytes_t *bytes) { + bytes->_val = _z_bytes_writer_finish(&serializer->_this._val._writer); +} + +ze_deserializer_t ze_deserializer_from_bytes(const z_loaned_bytes_t *bytes) { + ze_deserializer_t d; + d._reader = z_bytes_get_reader(bytes); + return d; +} + +z_result_t __read_single_byte(uint8_t *b, void *context) { + z_bytes_reader_t *reader = (z_bytes_reader_t *)context; + return _z_bytes_reader_read(reader, b, 1) == 1 ? _Z_RES_OK : _Z_ERR_DID_NOT_READ; +} + +z_result_t __read_zint(z_bytes_reader_t *reader, _z_zint_t *zint) { + return _z_zsize_decode_with_reader(zint, __read_single_byte, reader); +} + +z_result_t ze_serializer_serialize_sequence_length(ze_loaned_serializer_t *serializer, size_t len) { + uint8_t buf[16]; + size_t bytes_used = _z_zsize_encode_buf(buf, len); + return _z_bytes_writer_write_all(&serializer->_writer, buf, bytes_used); +} + +z_result_t ze_deserializer_deserialize_sequence_length(ze_deserializer_t *deserializer, size_t *len) { + return __read_zint(&deserializer->_reader, len); +} + +z_result_t ze_serializer_serialize_buf(ze_loaned_serializer_t *serializer, const uint8_t *val, size_t len) { + _Z_RETURN_IF_ERR(ze_serializer_serialize_sequence_length(serializer, len)); + _Z_RETURN_IF_ERR(_z_bytes_writer_write_all(&serializer->_writer, val, len)); + return Z_OK; +} + +z_result_t ze_serializer_serialize_slice(ze_loaned_serializer_t *serializer, const z_loaned_slice_t *val) { + return ze_serializer_serialize_buf(serializer, z_slice_data(val), z_slice_len(val)); +} + +z_result_t ze_deserializer_deserialize_slice(ze_deserializer_t *deserializer, z_owned_slice_t *val) { + size_t len = 0; + _Z_RETURN_IF_ERR(ze_deserializer_deserialize_sequence_length(deserializer, &len)); + _Z_RETURN_IF_ERR(_z_slice_init(&val->_val, len)); + if (z_bytes_reader_read(&deserializer->_reader, (uint8_t *)val->_val.start, len) != len) { + _z_slice_clear(&val->_val); + return _Z_ERR_DID_NOT_READ; + }; + return Z_OK; +} + +z_result_t ze_serializer_serialize_str(ze_loaned_serializer_t *serializer, const char *val) { + size_t len = strlen(val); + return ze_serializer_serialize_buf(serializer, (const uint8_t *)val, len); +} + +z_result_t ze_serializer_serialize_string(ze_loaned_serializer_t *serializer, const z_loaned_string_t *val) { + return ze_serializer_serialize_buf(serializer, (const uint8_t *)z_string_data(val), z_string_len(val)); +} + +z_result_t ze_deserializer_deserialize_string(ze_deserializer_t *deserializer, z_owned_string_t *val) { + z_owned_slice_t s; + _Z_RETURN_IF_ERR(ze_deserializer_deserialize_slice(deserializer, &s)); + val->_val._slice = s._val; + return _Z_RES_OK; +} + +#define _Z_BUILD_BYTES_FROM_SERIALIZER(expr) \ + z_bytes_empty(bytes); \ + _ze_serializer_t serializer = _ze_serializer_empty(); \ + _Z_CLEAN_RETURN_IF_ERR(expr, _ze_serializer_clear(&serializer)); \ + bytes->_val = _z_bytes_writer_finish(&serializer._writer); + +z_result_t ze_serialize_buf(z_owned_bytes_t *bytes, const uint8_t *data, size_t len) { + _Z_BUILD_BYTES_FROM_SERIALIZER(ze_serializer_serialize_buf(&serializer, data, len)); + return _Z_RES_OK; +} + +z_result_t ze_serialize_slice(z_owned_bytes_t *bytes, const z_loaned_slice_t *data) { + _Z_BUILD_BYTES_FROM_SERIALIZER(ze_serializer_serialize_slice(&serializer, data)); + return _Z_RES_OK; +} + +z_result_t ze_deserialize_slice(const z_loaned_bytes_t *bytes, z_owned_slice_t *data) { + ze_deserializer_t deserializer = ze_deserializer_from_bytes(bytes); + return ze_deserializer_deserialize_slice(&deserializer, data); +} + +z_result_t ze_serialize_str(z_owned_bytes_t *bytes, const char *data) { + _Z_BUILD_BYTES_FROM_SERIALIZER(ze_serializer_serialize_str(&serializer, data)); + return _Z_RES_OK; +} + +z_result_t ze_serialize_string(z_owned_bytes_t *bytes, const z_loaned_string_t *data) { + _Z_BUILD_BYTES_FROM_SERIALIZER(ze_serializer_serialize_string(&serializer, data)); + return _Z_RES_OK; +} + +z_result_t ze_deserialize_string(const z_loaned_bytes_t *bytes, z_owned_string_t *data) { + ze_deserializer_t deserializer = ze_deserializer_from_bytes(bytes); + return ze_deserializer_deserialize_string(&deserializer, data); +} + +#define _Z_IMPLEMENT_ZBYTES_ARITHMETIC(suffix, type) \ + z_result_t ze_serialize_##suffix(z_owned_bytes_t *bytes, type data) { \ + _Z_BUILD_BYTES_FROM_SERIALIZER(ze_serializer_serialize_##suffix(&serializer, data)) \ + return _Z_RES_OK; \ + } \ + z_result_t ze_deserialize_##suffix(const z_loaned_bytes_t *bytes, type *data) { \ + ze_deserializer_t deserializer = ze_deserializer_from_bytes(bytes); \ + z_result_t err = ze_deserializer_deserialize_##suffix(&deserializer, data); \ + if (err == Z_OK && !ze_deserializer_is_done(&deserializer)) { \ + err = Z_EDESERIALIZE; \ + } \ + return err; \ + } + +_Z_IMPLEMENT_ZBYTES_ARITHMETIC(uint8, uint8_t) +_Z_IMPLEMENT_ZBYTES_ARITHMETIC(uint16, uint16_t) +_Z_IMPLEMENT_ZBYTES_ARITHMETIC(uint32, uint32_t) +_Z_IMPLEMENT_ZBYTES_ARITHMETIC(uint64, uint64_t) +_Z_IMPLEMENT_ZBYTES_ARITHMETIC(int8, int8_t) +_Z_IMPLEMENT_ZBYTES_ARITHMETIC(int16, int16_t) +_Z_IMPLEMENT_ZBYTES_ARITHMETIC(int32, int32_t) +_Z_IMPLEMENT_ZBYTES_ARITHMETIC(int64, int64_t) +_Z_IMPLEMENT_ZBYTES_ARITHMETIC(float, float) +_Z_IMPLEMENT_ZBYTES_ARITHMETIC(double, double) + +bool ze_deserializer_is_done(const ze_deserializer_t *deserializer) { + return _z_bytes_reader_remaining(&deserializer->_reader) == 0; +} +#endif diff --git a/src/collections/bytes.c b/src/collections/bytes.c index 418c8f873..698e4bb5a 100644 --- a/src/collections/bytes.c +++ b/src/collections/bytes.c @@ -115,6 +115,8 @@ z_result_t _z_bytes_from_buf(_z_bytes_t *b, const uint8_t *src, size_t len) { } z_result_t _z_bytes_to_slice(const _z_bytes_t *bytes, _z_slice_t *s) { + // TODO: consider return a slice with custom deleter referencing the corresponding _arc_slice + // to avoid extra copy // Allocate slice size_t len = _z_bytes_len(bytes); *s = _z_slice_make(len); @@ -154,97 +156,6 @@ z_result_t _z_bytes_append_bytes(_z_bytes_t *dst, _z_bytes_t *src) { return res; } -z_result_t _z_bytes_from_pair(_z_bytes_t *out, _z_bytes_t *first, _z_bytes_t *second) { - *out = _z_bytes_null(); - _z_bytes_iterator_writer_t writer = _z_bytes_get_iterator_writer(out, 0); - _Z_CLEAN_RETURN_IF_ERR(_z_bytes_iterator_writer_write(&writer, first), _z_bytes_drop(second)); - _Z_CLEAN_RETURN_IF_ERR(_z_bytes_iterator_writer_write(&writer, second), _z_bytes_drop(out)); - - return _Z_RES_OK; -} - -z_result_t _z_bytes_deserialize_into_pair(const _z_bytes_t *bs, _z_bytes_t *first_out, _z_bytes_t *second_out) { - _z_bytes_iterator_t iter = _z_bytes_get_iterator(bs); - z_result_t res = _z_bytes_iterator_next(&iter, first_out); - if (res != _Z_RES_OK) return res; - res = _z_bytes_iterator_next(&iter, second_out); - if (res != _Z_RES_OK) { - _z_bytes_drop(first_out); - }; - return res; -} - -z_result_t _z_bytes_to_uint8(const _z_bytes_t *bs, uint8_t *val) { - *val = 0; - return _z_bytes_to_buf(bs, val, sizeof(uint8_t)) == sizeof(uint8_t) ? _Z_RES_OK : _Z_ERR_DID_NOT_READ; -} - -z_result_t _z_bytes_to_uint16(const _z_bytes_t *bs, uint16_t *val) { - *val = 0; - uint8_t buf[sizeof(uint16_t)] = {0}; - if (_z_bytes_to_buf(bs, buf, sizeof(uint16_t)) == 0) { - return _Z_ERR_DID_NOT_READ; - } - *val = _z_host_le_load16(buf); - return _Z_RES_OK; -} - -z_result_t _z_bytes_to_uint32(const _z_bytes_t *bs, uint32_t *val) { - *val = 0; - uint8_t buf[sizeof(uint32_t)] = {0}; - if (_z_bytes_to_buf(bs, buf, sizeof(uint32_t)) == 0) { - return _Z_ERR_DID_NOT_READ; - } - *val = _z_host_le_load32(buf); - return _Z_RES_OK; -} - -z_result_t _z_bytes_to_uint64(const _z_bytes_t *bs, uint64_t *val) { - *val = 0; - uint8_t buf[sizeof(uint64_t)] = {0}; - if (_z_bytes_to_buf(bs, buf, sizeof(uint64_t)) == 0) { - return _Z_ERR_DID_NOT_READ; - } - *val = _z_host_le_load64(buf); - return _Z_RES_OK; -} - -z_result_t _z_bytes_to_float(const _z_bytes_t *bs, float *val) { - *val = 0; - return _z_bytes_to_buf(bs, (uint8_t *)val, sizeof(float)) == sizeof(float) ? _Z_RES_OK : _Z_ERR_DID_NOT_READ; -} - -z_result_t _z_bytes_to_double(const _z_bytes_t *bs, double *val) { - *val = 0; - return _z_bytes_to_buf(bs, (uint8_t *)val, sizeof(double)) == sizeof(double) ? _Z_RES_OK : _Z_ERR_DID_NOT_READ; -} - -z_result_t _z_bytes_from_uint8(_z_bytes_t *b, uint8_t val) { return _z_bytes_from_buf(b, &val, sizeof(val)); } - -z_result_t _z_bytes_from_uint16(_z_bytes_t *b, uint16_t val) { - uint8_t buf[sizeof(uint16_t)]; - size_t len = _z_host_le_store16(val, buf); - return _z_bytes_from_buf(b, buf, len); -} - -z_result_t _z_bytes_from_uint32(_z_bytes_t *b, uint32_t val) { - uint8_t buf[sizeof(uint32_t)]; - size_t len = _z_host_le_store32(val, buf); - return _z_bytes_from_buf(b, buf, len); -} - -z_result_t _z_bytes_from_uint64(_z_bytes_t *b, uint64_t val) { - uint8_t buf[sizeof(uint64_t)]; - size_t len = _z_host_le_store64(val, buf); - return _z_bytes_from_buf(b, buf, len); -} - -z_result_t _z_bytes_from_float(_z_bytes_t *b, float val) { return _z_bytes_from_buf(b, (uint8_t *)&val, sizeof(val)); } - -z_result_t _z_bytes_from_double(_z_bytes_t *b, double val) { - return _z_bytes_from_buf(b, (uint8_t *)&val, sizeof(val)); -} - _z_slice_t _z_bytes_try_get_contiguous(const _z_bytes_t *bs) { if (_z_bytes_num_slices(bs) == 1) { _z_arc_slice_t *arc_s = _z_bytes_get_slice(bs, 0); @@ -367,15 +278,6 @@ size_t _z_bytes_reader_read(_z_bytes_reader_t *reader, uint8_t *buf, size_t len) return to_read - len; } -z_result_t __read_single_byte(uint8_t *b, void *context) { - _z_bytes_reader_t *reader = (_z_bytes_reader_t *)context; - return _z_bytes_reader_read(reader, b, 1) == 1 ? _Z_RES_OK : _Z_ERR_DID_NOT_READ; -} - -z_result_t _z_bytes_reader_read_zint(_z_bytes_reader_t *reader, _z_zint_t *zint) { - return _z_zsize_decode_with_reader(zint, __read_single_byte, reader); -} - z_result_t _z_bytes_reader_read_slices(_z_bytes_reader_t *reader, size_t len, _z_bytes_t *out) { *out = _z_bytes_null(); z_result_t res = _Z_RES_OK; @@ -413,34 +315,32 @@ z_result_t _z_bytes_reader_read_slices(_z_bytes_reader_t *reader, size_t len, _z return res; } -_z_bytes_iterator_t _z_bytes_get_iterator(const _z_bytes_t *bytes) { - return (_z_bytes_iterator_t){._reader = _z_bytes_get_reader(bytes)}; +_z_bytes_writer_t _z_bytes_writer_from_bytes(_z_bytes_t *bytes) { + _z_bytes_writer_t writer; + writer.cache = NULL; + _z_bytes_move(&writer.bytes, bytes); + return writer; } -z_result_t _z_bytes_iterator_next(_z_bytes_iterator_t *iter, _z_bytes_t *b) { - *b = _z_bytes_null(); - _z_zint_t len; - if (_z_bytes_reader_read_zint(&iter->_reader, &len) != _Z_RES_OK) { - return _Z_ERR_DID_NOT_READ; - } - return _z_bytes_reader_read_slices(&iter->_reader, len, b); +_z_bytes_writer_t _z_bytes_writer_empty(void) { + _z_bytes_writer_t writer; + writer.cache = NULL; + writer.bytes = _z_bytes_null(); + return writer; } -_z_bytes_writer_t _z_bytes_get_writer(_z_bytes_t *bytes, size_t cache_size) { - return (_z_bytes_writer_t){.cache = NULL, .cache_size = cache_size, .bytes = bytes}; -} +bool _z_bytes_writer_is_empty(const _z_bytes_writer_t *writer) { return _z_bytes_is_empty(&writer->bytes); } + +bool _z_bytes_writer_check(const _z_bytes_writer_t *writer) { return !_z_bytes_writer_is_empty(writer); } z_result_t _z_bytes_writer_ensure_cache(_z_bytes_writer_t *writer) { - // first we check if cache stayed untouched since previous write operation - if (writer->cache != NULL) { - _z_arc_slice_t *arc_s = _z_bytes_get_slice(writer->bytes, _z_bytes_num_slices(writer->bytes) - 1); - if (_Z_RC_IN_VAL(&arc_s->slice)->start + arc_s->len == writer->cache) { - if (_Z_RC_IN_VAL(&arc_s->slice)->len > arc_s->len) return _Z_RES_OK; - } + assert(writer->cache != NULL); + + if (_Z_RC_IN_VAL(&writer->cache->slice)->len > writer->cache->len) { + return _Z_RES_OK; } // otherwise we allocate a new cache - assert(writer->cache_size > 0); - _z_slice_t s = _z_slice_make(writer->cache_size); + _z_slice_t s = _z_slice_make(writer->cache->len * 2); if (s.start == NULL) return _Z_ERR_SYSTEM_OUT_OF_MEMORY; _z_arc_slice_t cache = _z_arc_slice_wrap(s, 0, 0); if (_Z_RC_IS_NULL(&cache.slice)) { @@ -448,50 +348,75 @@ z_result_t _z_bytes_writer_ensure_cache(_z_bytes_writer_t *writer) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } - _Z_CLEAN_RETURN_IF_ERR(_z_bytes_append_slice(writer->bytes, &cache), _z_arc_slice_drop(&cache)); - writer->cache = (uint8_t *)_Z_RC_IN_VAL(&cache.slice)->start; + _Z_CLEAN_RETURN_IF_ERR(_z_bytes_append_slice(&writer->bytes, &cache), _z_arc_slice_drop(&cache)); + writer->cache = _z_bytes_get_slice(&writer->bytes, _z_bytes_num_slices(&writer->bytes) - 1); + return _Z_RES_OK; +} + +z_result_t _z_bytes_writer_init_cache(_z_bytes_writer_t *writer, const uint8_t *src, size_t len) { + assert(writer->cache == NULL); + + _z_slice_t s = _z_slice_copy_from_buf(src, len); + if (s.len != len) return _Z_ERR_SYSTEM_OUT_OF_MEMORY; + _z_arc_slice_t arc_s = _z_arc_slice_wrap(s, 0, len); + if (_Z_RC_IS_NULL(&arc_s.slice)) { + _z_slice_clear(&s); + return _Z_ERR_SYSTEM_OUT_OF_MEMORY; + } + + _Z_RETURN_IF_ERR(_z_bytes_append_slice(&writer->bytes, &arc_s)); + writer->cache = _z_bytes_get_slice(&writer->bytes, _z_bytes_num_slices(&writer->bytes) - 1); return _Z_RES_OK; } z_result_t _z_bytes_writer_write_all(_z_bytes_writer_t *writer, const uint8_t *src, size_t len) { - if (writer->cache_size == 0) { // no cache - append data as a single slice - _z_slice_t s = _z_slice_copy_from_buf(src, len); - if (s.len != len) return _Z_ERR_SYSTEM_OUT_OF_MEMORY; - _z_arc_slice_t arc_s = _z_arc_slice_wrap(s, 0, len); - if (_Z_RC_IS_NULL(&arc_s.slice)) { - _z_slice_clear(&s); - return _Z_ERR_SYSTEM_OUT_OF_MEMORY; - } - return _z_bytes_append_slice(writer->bytes, &arc_s); + if (writer->cache == NULL) { // no cache - append data as a single slice + return _z_bytes_writer_init_cache(writer, src, len); } while (len > 0) { _Z_RETURN_IF_ERR(_z_bytes_writer_ensure_cache(writer)); - _z_arc_slice_t *arc_s = _z_bytes_get_slice(writer->bytes, _z_bytes_num_slices(writer->bytes) - 1); - size_t remaining_in_cache = _Z_RC_IN_VAL(&arc_s->slice)->len - arc_s->len; + size_t remaining_in_cache = _Z_RC_IN_VAL(&writer->cache->slice)->len - writer->cache->len; size_t to_copy = remaining_in_cache < len ? remaining_in_cache : len; - memcpy(writer->cache, src, to_copy); + uint8_t *buffer_start = (uint8_t *)_Z_RC_IN_VAL(&writer->cache->slice)->start + writer->cache->len; + memcpy(buffer_start, src, to_copy); len -= to_copy; - arc_s->len += to_copy; + writer->cache->len += to_copy; src += to_copy; - writer->cache += to_copy; } return _Z_RES_OK; } -z_result_t _z_bytes_writer_append(_z_bytes_writer_t *writer, _z_bytes_t *src) { - _Z_CLEAN_RETURN_IF_ERR(_z_bytes_append_bytes(writer->bytes, src), _z_bytes_drop(src)); +z_result_t _z_bytes_writer_append_z_bytes(_z_bytes_writer_t *writer, _z_bytes_t *src) { + _Z_CLEAN_RETURN_IF_ERR(_z_bytes_append_bytes(&writer->bytes, src), _z_bytes_drop(src)); writer->cache = NULL; return _Z_RES_OK; } -_z_bytes_iterator_writer_t _z_bytes_get_iterator_writer(_z_bytes_t *bytes, size_t cache_size) { - return (_z_bytes_iterator_writer_t){.writer = _z_bytes_get_writer(bytes, cache_size)}; +z_result_t _z_bytes_writer_append_slice(_z_bytes_writer_t *writer, _z_arc_slice_t *src) { + _Z_CLEAN_RETURN_IF_ERR(_z_bytes_append_slice(&writer->bytes, src), _z_arc_slice_drop(src)); + writer->cache = NULL; + return _Z_RES_OK; +} + +_z_bytes_t _z_bytes_writer_finish(_z_bytes_writer_t *writer) { + _z_bytes_t out; + _z_bytes_move(&out, &writer->bytes); + writer->cache = NULL; + return out; +} + +void _z_bytes_writer_clear(_z_bytes_writer_t *writer) { + _z_bytes_drop(&writer->bytes); + writer->cache = NULL; +} + +void _z_bytes_writer_move(_z_bytes_writer_t *dst, _z_bytes_writer_t *src) { + dst->cache = src->cache; + _z_bytes_move(&dst->bytes, &src->bytes); + src->cache = NULL; } -z_result_t _z_bytes_iterator_writer_write(_z_bytes_iterator_writer_t *writer, _z_bytes_t *src) { - uint8_t l_buf[16]; - size_t l_len = _z_zsize_encode_buf(l_buf, _z_bytes_len(src)); - _Z_CLEAN_RETURN_IF_ERR(_z_bytes_writer_write_all(&writer->writer, l_buf, l_len), _z_bytes_drop(src)); - return _z_bytes_writer_append(&writer->writer, src); +size_t _z_bytes_reader_remaining(const _z_bytes_reader_t *reader) { + return _z_bytes_len(reader->bytes) - reader->byte_idx; } diff --git a/src/utils/endianness.c b/src/utils/endianness.c deleted file mode 100644 index 46be4a7c2..000000000 --- a/src/utils/endianness.c +++ /dev/null @@ -1,134 +0,0 @@ -// -// Copyright (c) 2024 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// - -#include "zenoh-pico/utils/endianness.h" - -#if !defined(ZENOH_ENDIANNNESS_BIG) && !defined(ZENOH_ENDIANNNESS_LITTLE) -// Gcc/clang test -#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define ZENOH_ENDIANNNESS_BIG -#else -#define ZENOH_ENDIANNNESS_LITTLE -#endif -#endif - -// *** Little endian *** -uint16_t _z_le_load16(const uint8_t *src) { return (uint16_t)(src[0] << 0) | (uint16_t)(src[1] << 8); } - -uint32_t _z_le_load32(const uint8_t *src) { - return ((uint32_t)src[0] << 0) | ((uint32_t)src[1] << 8) | ((uint32_t)src[2] << 16) | ((uint32_t)src[3] << 24); -} - -uint64_t _z_le_load64(const uint8_t *src) { - return ((uint64_t)src[0] << 0) | ((uint64_t)src[1] << 8) | ((uint64_t)src[2] << 16) | ((uint64_t)src[3] << 24) | - ((uint64_t)src[4] << 32) | ((uint64_t)src[5] << 40) | ((uint64_t)src[6] << 48) | ((uint64_t)src[7] << 56); -} - -#define _Z_LE_STORE_IMPL(SIZE) \ - size_t _z_le_store##SIZE(uint##SIZE##_t val, uint8_t *dst) { \ - size_t len = 1; \ - for (size_t i = 0; i < sizeof(val); ++i) { \ - if (val != 0) { \ - len = i + 1; \ - } \ - dst[i] = (uint8_t)val; \ - val = val >> 8; \ - } \ - return len; \ - } - -_Z_LE_STORE_IMPL(16) -_Z_LE_STORE_IMPL(32) -_Z_LE_STORE_IMPL(64) - -// *** Big endian *** -uint16_t _z_be_load16(const uint8_t *src) { return (uint16_t)(src[0] << 8) | (uint16_t)(src[1] << 0); } - -uint32_t _z_be_load32(const uint8_t *src) { - return ((uint32_t)src[0] << 24) | ((uint32_t)src[1] << 16) | ((uint32_t)src[2] << 8) | ((uint32_t)src[3] << 0); -} - -uint64_t _z_be_load64(const uint8_t *src) { - return ((uint64_t)src[0] << 56) | ((uint64_t)src[1] << 48) | ((uint64_t)src[2] << 40) | ((uint64_t)src[3] << 32) | - ((uint64_t)src[4] << 24) | ((uint64_t)src[5] << 16) | ((uint64_t)src[6] << 8) | ((uint64_t)src[7] << 0); -} - -#define _Z_BE_STORE_IMPL(SIZE) \ - size_t _z_be_store##SIZE(uint##SIZE##_t val, uint8_t *dst) { \ - size_t len = 1; \ - for (size_t i = 0; i < sizeof(val); ++i) { \ - if (val != 0) { \ - len = i + 1; \ - } \ - dst[sizeof(val) - 1 - i] = (uint8_t)val; \ - val = val >> 8; \ - } \ - return len; \ - } - -_Z_BE_STORE_IMPL(16) -_Z_BE_STORE_IMPL(32) -_Z_BE_STORE_IMPL(64) - -// *** Host *** -uint16_t _z_host_le_load16(const uint8_t *src) { -#if defined(ZENOH_ENDIANNNESS_BIG) - return _z_be_load16(src); -#elif defined(ZENOH_ENDIANNNESS_LITTLE) - return _z_le_load16(src); -#endif -} - -uint32_t _z_host_le_load32(const uint8_t *src) { -#if defined(ZENOH_ENDIANNNESS_BIG) - return _z_be_load32(src); -#elif defined(ZENOH_ENDIANNNESS_LITTLE) - return _z_le_load32(src); -#endif -} - -uint64_t _z_host_le_load64(const uint8_t *src) { -#if defined(ZENOH_ENDIANNNESS_BIG) - return _z_be_load64(src); -#elif defined(ZENOH_ENDIANNNESS_LITTLE) - return _z_le_load64(src); -#endif -} - -size_t _z_host_le_store16(const uint16_t val, uint8_t *dst) { -#if defined(ZENOH_ENDIANNNESS_BIG) - return _z_be_store16(val, dst); -#elif defined(ZENOH_ENDIANNNESS_LITTLE) - return _z_le_store16(val, dst); -#endif -} -size_t _z_host_le_store32(const uint32_t val, uint8_t *dst) { -#if defined(ZENOH_ENDIANNNESS_BIG) - return _z_be_store32(val, dst); -#elif defined(ZENOH_ENDIANNNESS_LITTLE) - return _z_le_store32(val, dst); -#endif -} - -size_t _z_host_le_store64(const uint64_t val, uint8_t *dst) { -#if defined(ZENOH_ENDIANNNESS_BIG) - return _z_be_store64(val, dst); -#elif defined(ZENOH_ENDIANNNESS_LITTLE) - return _z_le_store64(val, dst); -#endif -} - -uint8_t _z_get_u16_lsb(uint_fast16_t val) { return (uint8_t)(val >> 0); } - -uint8_t _z_get_u16_msb(uint_fast16_t val) { return (uint8_t)(val >> 8); } diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 9b95d33d0..43d765cdb 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -337,7 +337,7 @@ int main(int argc, char **argv) { printf("Publisher Put..."); // Create payload - z_bytes_serialize_from_str(&payload, value); + z_bytes_copy_from_str(&payload, value); z_publisher_put_options_t _ret_pput_opt; z_publisher_put_options_default(&_ret_pput_opt); diff --git a/tests/z_api_bytes_test.c b/tests/z_api_bytes_test.c index 0393302e5..4b241d99b 100644 --- a/tests/z_api_bytes_test.c +++ b/tests/z_api_bytes_test.c @@ -17,6 +17,7 @@ #include #include "zenoh-pico/api/primitives.h" +#include "zenoh-pico/api/serialization.h" #include "zenoh-pico/api/types.h" #undef NDEBUG @@ -61,15 +62,19 @@ void test_reader_read(void) { z_bytes_reader_t reader = z_bytes_get_reader(z_bytes_loan(&payload)); assert(5 == z_bytes_reader_read(&reader, data_out, 5)); + assert(5 == z_bytes_reader_remaining(&reader)); z_bytes_reader_seek(&reader, 2, SEEK_CUR); assert(2 == z_bytes_reader_read(&reader, data_out + 7, 2)); + assert(1 == z_bytes_reader_remaining(&reader)); z_bytes_reader_seek(&reader, 5, SEEK_SET); assert(2 == z_bytes_reader_read(&reader, data_out + 5, 2)); + assert(3 == z_bytes_reader_remaining(&reader)); z_bytes_reader_seek(&reader, -1, SEEK_END); assert(1 == z_bytes_reader_read(&reader, data_out + 9, 10)); + assert(0 == z_bytes_reader_remaining(&reader)); assert(0 == z_bytes_reader_read(&reader, data_out, 10)); @@ -82,14 +87,15 @@ void test_writer(void) { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; uint8_t data_out[10] = {0}; - z_owned_bytes_t payload; - z_bytes_empty(&payload); + z_owned_bytes_writer_t writer; + z_bytes_writer_empty(&writer); - z_bytes_writer_t writer = z_bytes_get_writer(z_bytes_loan_mut(&payload)); + assert(z_bytes_writer_write_all(z_bytes_writer_loan_mut(&writer), data, 3) == 0); + assert(z_bytes_writer_write_all(z_bytes_writer_loan_mut(&writer), data + 3, 5) == 0); + assert(z_bytes_writer_write_all(z_bytes_writer_loan_mut(&writer), data + 8, 2) == 0); - assert(z_bytes_writer_write_all(&writer, data, 3) == 0); - assert(z_bytes_writer_write_all(&writer, data + 3, 5) == 0); - assert(z_bytes_writer_write_all(&writer, data + 8, 2) == 0); + z_owned_bytes_t payload; + z_bytes_writer_finish(z_bytes_writer_move(&writer), &payload); z_bytes_reader_t reader = z_bytes_get_reader(z_bytes_loan(&payload)); @@ -99,64 +105,23 @@ void test_writer(void) { z_bytes_drop(z_bytes_move(&payload)); } -void test_bounded(void) { - uint32_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - uint32_t data_out[10] = {0}; - - z_owned_bytes_t payload; - z_bytes_empty(&payload); - - z_bytes_writer_t 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_uint32(&b, data[i]); - assert(z_bytes_writer_append_bounded(&writer, z_bytes_move(&b)) == 0); - } - { - z_owned_bytes_t b; - z_bytes_serialize_from_str(&b, "test"); - assert(z_bytes_writer_append_bounded(&writer, z_bytes_move(&b)) == 0); - } - - z_bytes_reader_t reader = z_bytes_get_reader(z_bytes_loan(&payload)); - - for (size_t i = 0; i < 10; ++i) { - z_owned_bytes_t b; - assert(z_bytes_reader_read_bounded(&reader, &b) == 0); - assert(z_bytes_deserialize_into_uint32(z_bytes_loan(&b), &data_out[i]) == 0); - z_bytes_drop(z_bytes_move(&b)); - } - assert(!memcmp(data, data_out, 10)); - { - z_owned_string_t s; - z_owned_bytes_t b; - assert(z_bytes_reader_read_bounded(&reader, &b) == 0); - z_bytes_deserialize_into_string(z_bytes_loan(&b), &s); - assert(strncmp("test", z_string_data(z_string_loan(&s)), z_string_len(z_string_loan(&s))) == 0); - z_bytes_drop(z_bytes_move(&b)); - z_string_drop(z_string_move(&s)); - } - uint8_t d; - assert(0 == z_bytes_reader_read(&reader, &d, 1)); // we reached the end of the payload - - z_bytes_drop(z_bytes_move(&payload)); -} - void test_append(void) { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; uint8_t data_out[10] = {0}; z_owned_bytes_t payload; - z_bytes_empty(&payload); + z_bytes_copy_from_buf(&payload, data, 5); - z_bytes_writer_t writer = z_bytes_get_writer(z_bytes_loan_mut(&payload)); - z_bytes_writer_write_all(&writer, data, 5); + z_owned_bytes_writer_t writer; + z_bytes_writer_empty(&writer); + z_bytes_writer_append(z_bytes_writer_loan_mut(&writer), z_bytes_move(&payload)); { z_owned_bytes_t b; - z_bytes_serialize_from_buf(&b, data + 5, 5); - assert(z_bytes_writer_append(&writer, z_bytes_move(&b)) == 0); + z_bytes_copy_from_buf(&b, data + 5, 5); + assert(z_bytes_writer_append(z_bytes_writer_loan_mut(&writer), z_bytes_move(&b)) == 0); } + z_bytes_writer_finish(z_bytes_writer_move(&writer), &payload); z_bytes_reader_t reader = z_bytes_get_reader(z_bytes_loan(&payload)); z_bytes_reader_read(&reader, data_out, 10); @@ -176,7 +141,7 @@ void custom_deleter(void *data, void *context) { bool z_check_and_drop_payload(z_owned_bytes_t *payload, uint8_t *data, size_t len) { z_owned_slice_t out; - z_bytes_deserialize_into_slice(z_bytes_loan(payload), &out); + z_bytes_to_slice(z_bytes_loan(payload), &out); z_bytes_drop(z_bytes_move(payload)); bool res = memcmp(data, z_slice_data(z_slice_loan(&out)), len) == 0; z_slice_drop(z_slice_move(&out)); @@ -192,7 +157,7 @@ void test_slice(void) { z_bytes_from_buf(&payload, data, 10, custom_deleter, (void *)&cnt); z_owned_slice_t out; - z_bytes_deserialize_into_slice(z_bytes_loan(&payload), &out); + z_bytes_to_slice(z_bytes_loan(&payload), &out); assert(cnt == 0); z_bytes_drop(z_bytes_move(&payload)); @@ -204,7 +169,7 @@ void test_slice(void) { z_owned_bytes_t payload2; z_owned_slice_t s; z_slice_copy_from_buf(&s, data, 10); - z_bytes_serialize_from_slice(&payload2, z_slice_loan(&s)); + z_bytes_copy_from_slice(&payload2, z_slice_loan(&s)); assert(z_internal_slice_check(&s)); z_slice_drop(z_slice_move(&s)); assert(z_check_and_drop_payload(&payload2, data, 10)); @@ -216,22 +181,22 @@ void test_slice(void) { assert(z_check_and_drop_payload(&payload3, data, 10)); z_owned_bytes_t payload4; - z_bytes_serialize_from_buf(&payload4, data, 10); + z_bytes_copy_from_buf(&payload4, data, 10); assert(z_check_and_drop_payload(&payload4, data, 10)); z_owned_bytes_t payload5; z_bytes_from_static_buf(&payload5, data, 10); assert(z_check_and_drop_payload(&payload5, data, 10)); } - -#define TEST_ARITHMETIC(TYPE, EXT, VAL) \ - { \ - TYPE in = VAL, out; \ - z_owned_bytes_t payload; \ - z_bytes_serialize_from_##EXT(&payload, in); \ - z_bytes_deserialize_into_##EXT(z_bytes_loan(&payload), &out); \ - assert(in == out); \ - z_bytes_drop(z_bytes_move(&payload)); \ +#if defined(Z_FEATURE_UNSTABLE_API) +#define TEST_ARITHMETIC(TYPE, EXT, VAL) \ + { \ + TYPE in = VAL, out; \ + z_owned_bytes_t payload; \ + ze_serialize_##EXT(&payload, in); \ + ze_deserialize_##EXT(z_bytes_loan(&payload), &out); \ + assert(in == out); \ + z_bytes_drop(z_bytes_move(&payload)); \ } void test_arithmetic(void) { @@ -248,57 +213,7 @@ void test_arithmetic(void) { TEST_ARITHMETIC(float, float, 10.1f); TEST_ARITHMETIC(double, double, -105.001); } - -bool iter_body(z_owned_bytes_t *b, void *context) { - uint8_t *val = (uint8_t *)context; - if (*val >= 10) { - return false; - } else { - z_bytes_serialize_from_uint8(b, *val); - } - *val = *val + 1; - return true; -} - -void test_iter(void) { - uint8_t data_out[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - z_owned_bytes_t payload; - uint8_t context = 0; - z_bytes_from_iter(&payload, iter_body, (void *)(&context)); - - z_bytes_iterator_t it = z_bytes_get_iterator(z_bytes_loan(&payload)); - - size_t i = 0; - z_owned_bytes_t out; - while (z_bytes_iterator_next(&it, &out)) { - uint8_t res; - z_bytes_deserialize_into_uint8(z_bytes_loan(&out), &res); - assert(res == data_out[i]); - i++; - z_bytes_drop(z_bytes_move(&out)); - } - assert(i == 10); - z_bytes_drop(z_bytes_move(&payload)); -} - -void test_pair(void) { - z_owned_bytes_t payload, payload1, payload2, payload1_out, payload2_out; - z_bytes_serialize_from_int16(&payload1, -500); - z_bytes_serialize_from_double(&payload2, 123.45); - z_bytes_from_pair(&payload, z_bytes_move(&payload1), z_bytes_move(&payload2)); - - z_bytes_deserialize_into_pair(z_bytes_loan(&payload), &payload1_out, &payload2_out); - - int16_t i; - double d; - z_bytes_deserialize_into_int16(z_bytes_loan(&payload1_out), &i); - z_bytes_deserialize_into_double(z_bytes_loan(&payload2_out), &d); - - assert(i == -500); - assert(d == 123.45); -} - +#endif 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); @@ -319,38 +234,96 @@ 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_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); + 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); assert(check_slice(z_bytes_loan(&payload), data, 10)); z_bytes_drop(z_bytes_move(&payload)); - z_bytes_empty(&payload); + z_bytes_writer_empty(&writer); // possible multiple slices - writer = z_bytes_get_writer(z_bytes_loan_mut(&payload)); - + // reusing empty writer 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)); + z_bytes_copy_from_buf(&b, data + i, 1); + z_bytes_writer_append(z_bytes_writer_loan_mut(&writer), z_bytes_move(&b)); } + z_bytes_writer_finish(z_bytes_writer_move(&writer), &payload); assert(check_slice(z_bytes_loan(&payload), data, 10)); z_bytes_drop(z_bytes_move(&payload)); } +#if defined(Z_FEATURE_UNSTABLE_API) +void test_serialize_simple(void) { + z_owned_bytes_t b; + + ze_owned_serializer_t serializer; + ze_serializer_empty(&serializer); + + assert(ze_serializer_serialize_double(ze_serializer_loan_mut(&serializer), 0.5) == 0); + assert(ze_serializer_serialize_int32(ze_serializer_loan_mut(&serializer), -1111) == 0); + assert(ze_serializer_serialize_str(ze_serializer_loan_mut(&serializer), "abc") == 0); + ze_serializer_finish(ze_serializer_move(&serializer), &b); + double d; + int32_t i; + z_owned_string_t s; + + ze_deserializer_t deserializer = ze_deserializer_from_bytes(z_bytes_loan(&b)); + assert(!ze_deserializer_is_done(&deserializer)); + assert(ze_deserializer_deserialize_double(&deserializer, &d) == 0); + assert(ze_deserializer_deserialize_int32(&deserializer, &i) == 0); + assert(ze_deserializer_deserialize_string(&deserializer, &s) == 0); + assert(ze_deserializer_is_done(&deserializer)); + + assert(d == 0.5); + assert(i == -1111); + assert(strncmp("abc", z_string_data(z_string_loan(&s)), z_string_len(z_string_loan(&s))) == 0); + + z_string_drop(z_string_move(&s)); + z_bytes_drop(z_bytes_move(&b)); +} + +void test_serialize_sequence(void) { + uint32_t input[6] = {1, 2, 3, 100, 10000, 100000}; + z_owned_bytes_t b; + ze_owned_serializer_t serializer; + ze_serializer_empty(&serializer); + ze_serializer_serialize_sequence_length(ze_serializer_loan_mut(&serializer), 6); + for (size_t i = 0; i < 6; ++i) { + ze_serializer_serialize_uint32(ze_serializer_loan_mut(&serializer), input[i]); + } + + ze_serializer_finish(ze_serializer_move(&serializer), &b); + + ze_deserializer_t deserializer = ze_deserializer_from_bytes(z_bytes_loan(&b)); + size_t len = 0; + assert(!ze_deserializer_is_done(&deserializer)); + assert(ze_deserializer_deserialize_sequence_length(&deserializer, &len) == 0); + assert(len == 6); + for (size_t i = 0; i < 6; i++) { + uint32_t u = 0; + assert(ze_deserializer_deserialize_uint32(&deserializer, &u) == 0); + assert(u == input[i]); + } + assert(ze_deserializer_is_done(&deserializer)); + z_bytes_drop(z_bytes_move(&b)); +} +#endif int main(void) { test_reader_seek(); test_reader_read(); test_writer(); test_slice(); - test_arithmetic(); - test_bounded(); test_append(); - test_iter(); - test_pair(); test_slices(); +#if defined(Z_FEATURE_UNSTABLE_API) + test_arithmetic(); + test_serialize_simple(); + test_serialize_sequence(); +#endif } diff --git a/tests/z_bytes_test.c b/tests/z_bytes_test.c index cc1373d20..fcc3ba773 100644 --- a/tests/z_bytes_test.c +++ b/tests/z_bytes_test.c @@ -161,54 +161,28 @@ void test_reader_seek(void) { _z_bytes_drop(&b); } -void test_writer_no_cache(void) { +void test_writer(void) { uint8_t data1[5] = {1, 2, 3, 4, 5}; uint8_t data2[5] = {1, 2, 6, 7, 8}; uint8_t data3[3] = {3, 9, 10}; - _z_bytes_t b = _z_bytes_null(); - _z_bytes_writer_t writer = _z_bytes_get_writer(&b, 0); - - _z_bytes_writer_write_all(&writer, data1, 5); - assert(_z_bytes_len(&b) == 5); - assert(_z_bytes_num_slices(&b) == 1); - _z_bytes_writer_write_all(&writer, data2, 5); - assert(_z_bytes_len(&b) == 10); - assert(_z_bytes_num_slices(&b) == 2); - _z_bytes_writer_write_all(&writer, data3, 3); - assert(_z_bytes_len(&b) == 13); - assert(_z_bytes_num_slices(&b) == 3); - - assert(memcmp(data1, _z_arc_slice_data(_z_bytes_get_slice(&b, 0)), 5) == 0); - assert(memcmp(data2, _z_arc_slice_data(_z_bytes_get_slice(&b, 1)), 5) == 0); - assert(memcmp(data3, _z_arc_slice_data(_z_bytes_get_slice(&b, 2)), 3) == 0); - _z_bytes_drop(&b); -} - -void test_writer_with_cache(void) { - uint8_t data1[5] = {1, 2, 3, 4, 5}; - uint8_t data2[5] = {1, 2, 6, 7, 8}; - uint8_t data3[3] = {3, 9, 10}; + uint8_t data1_out[5] = {1, 2, 3, 4, 5}; + uint8_t data2_out[8] = {1, 2, 6, 7, 8, 3, 9, 10}; - uint8_t data1_out[7] = {1, 2, 3, 4, 5, 1, 2}; - uint8_t data2_out[6] = {6, 7, 8, 3, 9, 10}; - _z_bytes_t b = _z_bytes_null(); - _z_bytes_writer_t writer = _z_bytes_get_writer(&b, 7); + _z_bytes_writer_t writer = _z_bytes_writer_empty(); _z_bytes_writer_write_all(&writer, data1, 5); - assert(_z_bytes_len(&b) == 5); - assert(_z_bytes_num_slices(&b) == 1); _z_bytes_writer_write_all(&writer, data2, 5); - assert(_z_bytes_len(&b) == 10); - assert(_z_bytes_num_slices(&b) == 2); _z_bytes_writer_write_all(&writer, data3, 3); + _z_bytes_t b = _z_bytes_writer_finish(&writer); + assert(_z_bytes_len(&b) == 13); assert(_z_bytes_num_slices(&b) == 2); - assert(_z_arc_slice_len(_z_bytes_get_slice(&b, 0)) == 7); - assert(_z_arc_slice_len(_z_bytes_get_slice(&b, 1)) == 6); - assert(memcmp(data1_out, _z_arc_slice_data(_z_bytes_get_slice(&b, 0)), 7) == 0); - assert(memcmp(data2_out, _z_arc_slice_data(_z_bytes_get_slice(&b, 1)), 6) == 0); + assert(_z_arc_slice_len(_z_bytes_get_slice(&b, 0)) == 5); + assert(_z_arc_slice_len(_z_bytes_get_slice(&b, 1)) == 8); + assert(memcmp(data1_out, _z_arc_slice_data(_z_bytes_get_slice(&b, 0)), 5) == 0); + assert(memcmp(data2_out, _z_arc_slice_data(_z_bytes_get_slice(&b, 1)), 8) == 0); _z_bytes_drop(&b); } @@ -218,7 +192,6 @@ int main(void) { test_append(); test_reader_read(); test_reader_seek(); - test_writer_no_cache(); - test_writer_with_cache(); + test_writer(); return 0; } diff --git a/tests/z_channels_test.c b/tests/z_channels_test.c index 6af2e7a96..5bd241d53 100644 --- a/tests/z_channels_test.c +++ b/tests/z_channels_test.c @@ -39,23 +39,23 @@ z_call(*z_loan(closure), &sample); \ } while (0); -#define _RECV(handler, method, buf) \ - do { \ - z_owned_sample_t sample; \ - z_result_t res = method(z_loan(handler), &sample); \ - if (res == Z_CHANNEL_DISCONNECTED) { \ - strcpy(buf, "closed"); \ - } else if (res == Z_OK) { \ - z_owned_slice_t value; \ - z_bytes_deserialize_into_slice(z_sample_payload(z_loan(sample)), &value); \ - size_t value_len = z_slice_len(z_loan(value)); \ - strncpy(buf, (const char *)z_slice_data(z_loan(value)), value_len); \ - buf[value_len] = '\0'; \ - z_drop(z_move(sample)); \ - z_drop(z_move(value)); \ - } else if (res == Z_CHANNEL_NODATA) { \ - strcpy(buf, "nodata"); \ - } \ +#define _RECV(handler, method, buf) \ + do { \ + z_owned_sample_t sample; \ + z_result_t res = method(z_loan(handler), &sample); \ + if (res == Z_CHANNEL_DISCONNECTED) { \ + strcpy(buf, "closed"); \ + } else if (res == Z_OK) { \ + z_owned_slice_t value; \ + z_bytes_to_slice(z_sample_payload(z_loan(sample)), &value); \ + size_t value_len = z_slice_len(z_loan(value)); \ + strncpy(buf, (const char *)z_slice_data(z_loan(value)), value_len); \ + buf[value_len] = '\0'; \ + z_drop(z_move(sample)); \ + z_drop(z_move(value)); \ + } else if (res == Z_CHANNEL_NODATA) { \ + strcpy(buf, "nodata"); \ + } \ } while (0); #define RECV(handler, buf) _RECV(handler, z_recv, buf) diff --git a/tests/z_client_test.c b/tests/z_client_test.c index 12a399053..21d36e297 100644 --- a/tests/z_client_test.c +++ b/tests/z_client_test.c @@ -64,7 +64,7 @@ void query_handler(z_loaned_query_t *query, void *arg) { // Reply value encoding z_owned_bytes_t reply_payload; - z_bytes_serialize_from_str(&reply_payload, res); + z_bytes_copy_from_str(&reply_payload, res); z_query_reply(query, z_query_keyexpr(query), z_move(reply_payload), NULL); queries++; @@ -82,7 +82,7 @@ void reply_handler(z_loaned_reply_t *reply, void *arg) { z_view_string_t k_str, res_str; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &k_str); z_owned_string_t value; - z_bytes_deserialize_into_string(z_sample_payload(sample), &value); + z_bytes_to_string(z_sample_payload(sample), &value); assert(z_string_len(z_loan(value)) == strlen(res)); assert(strncmp(res, z_string_data(z_loan(value)), strlen(res)) == 0); z_view_string_from_str(&res_str, res); @@ -106,7 +106,7 @@ void data_handler(z_loaned_sample_t *sample, void *arg) { z_view_string_t k_str; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &k_str); z_owned_slice_t value; - z_bytes_deserialize_into_slice(z_sample_payload(sample), &value); + z_bytes_to_slice(z_sample_payload(sample), &value); size_t payload_len = z_slice_len(z_loan(value)); assert((payload_len == MSG_LEN) || (payload_len == FRAGMENT_MSG_LEN)); assert(_z_string_equals(z_loan(k_str), &res_str)); diff --git a/tests/z_peer_multicast_test.c b/tests/z_peer_multicast_test.c index 31fe89e50..3c8b0ba2c 100644 --- a/tests/z_peer_multicast_test.c +++ b/tests/z_peer_multicast_test.c @@ -48,7 +48,7 @@ void data_handler(z_loaned_sample_t *sample, void *arg) { z_view_string_t k_str; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &k_str); z_owned_slice_t value; - z_bytes_deserialize_into_slice(z_sample_payload(sample), &value); + z_bytes_to_slice(z_sample_payload(sample), &value); assert(z_slice_len(z_loan(value)) == MSG_LEN); assert(z_string_len(z_loan(k_str)) == strlen(res)); assert(strncmp(res, z_string_data(z_loan(k_str)), strlen(res)) == 0); diff --git a/tests/z_perf_rx.c b/tests/z_perf_rx.c index 442c5ac5c..07a8d48d7 100644 --- a/tests/z_perf_rx.c +++ b/tests/z_perf_rx.c @@ -42,7 +42,7 @@ void z_stats_stop(z_stats_t *stats) { void on_sample(z_loaned_sample_t *sample, void *context) { z_stats_t *stats = (z_stats_t *)context; z_owned_slice_t value; - z_bytes_deserialize_into_slice(z_sample_payload(sample), &value); + z_bytes_to_slice(z_sample_payload(sample), &value); unsigned long data_len = (unsigned long)z_slice_len(z_loan(value)); if (stats->curr_len != data_len) { diff --git a/tests/z_test_fragment_rx.c b/tests/z_test_fragment_rx.c index f550343bd..67481eaf2 100644 --- a/tests/z_test_fragment_rx.c +++ b/tests/z_test_fragment_rx.c @@ -24,7 +24,7 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); bool is_valid = true; z_owned_slice_t value; - z_bytes_deserialize_into_slice(z_sample_payload(sample), &value); + z_bytes_to_slice(z_sample_payload(sample), &value); const uint8_t *data = z_slice_data(z_loan(value)); size_t data_len = z_slice_len(z_loan(value)); for (size_t i = 0; i < data_len; i++) { diff --git a/zenohpico.pc b/zenohpico.pc index 5a3196e15..2afa72bf3 100644 --- a/zenohpico.pc +++ b/zenohpico.pc @@ -3,6 +3,6 @@ prefix=/usr/local Name: zenohpico Description: URL: -Version: 1.0.20240918dev +Version: 1.0.20240930dev Cflags: -I${prefix}/include Libs: -L${prefix}/lib -lzenohpico