From ab8f8de42865b439c405204b4e500091af426dd5 Mon Sep 17 00:00:00 2001 From: DenisBiryukov91 <155981813+DenisBiryukov91@users.noreply.github.com> Date: Thu, 4 Jul 2024 11:16:15 +0200 Subject: [PATCH] add z_encoding_from_substr function (#501) * added z_encoding_from_substr function; added encoding test * update docs * remove unrelated file --- CMakeLists.txt | 3 ++ docs/api.rst | 1 + include/zenoh-pico/api/primitives.h | 13 +++++ include/zenoh-pico/net/encoding.h | 2 +- src/api/api.c | 35 ++++++++---- src/net/encoding.c | 6 +-- tests/z_api_encoding_test.c | 82 +++++++++++++++++++++++++++++ 7 files changed, 127 insertions(+), 15 deletions(-) create mode 100644 tests/z_api_encoding_test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d23d59480..05ec5fab8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -377,6 +377,7 @@ if(UNIX OR MSVC) add_executable(z_perf_rx ${PROJECT_SOURCE_DIR}/tests/z_perf_rx.c) add_executable(z_bytes_test ${PROJECT_SOURCE_DIR}/tests/z_bytes_test.c) add_executable(z_api_bytes_test ${PROJECT_SOURCE_DIR}/tests/z_api_bytes_test.c) + add_executable(z_api_encoding_test ${PROJECT_SOURCE_DIR}/tests/z_api_encoding_test.c) target_link_libraries(z_data_struct_test ${Libname}) target_link_libraries(z_channels_test ${Libname}) @@ -393,6 +394,7 @@ if(UNIX OR MSVC) target_link_libraries(z_perf_rx ${Libname}) target_link_libraries(z_bytes_test ${Libname}) target_link_libraries(z_api_bytes_test ${Libname}) + target_link_libraries(z_api_encoding_test ${Libname}) configure_file(${PROJECT_SOURCE_DIR}/tests/modularity.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/modularity.py COPYONLY) configure_file(${PROJECT_SOURCE_DIR}/tests/raweth.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/raweth.py COPYONLY) @@ -412,6 +414,7 @@ if(UNIX OR MSVC) add_test(z_api_double_drop_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/z_api_double_drop_test) add_test(z_bytes_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/z_bytes_test) add_test(z_api_bytes_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/z_api_bytes_test) + add_test(z_api_encoding_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/z_api_encoding_test) endif() if(BUILD_MULTICAST) diff --git a/docs/api.rst b/docs/api.rst index def5fa04e..6584f9b76 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -317,6 +317,7 @@ Primitives .. autocfunction:: primitives.h::zp_config_get .. autocfunction:: primitives.h::zp_config_insert .. autocfunction:: primitives.h::z_encoding_from_str +.. autocfunction:: primitives.h::z_encoding_from_substr .. autocfunction:: primitives.h::z_encoding_to_string .. autocfunction:: primitives.h::z_reply_err_payload .. autocfunction:: primitives.h::z_reply_err_encoding diff --git a/include/zenoh-pico/api/primitives.h b/include/zenoh-pico/api/primitives.h index cfa0286e2..8bbec6b37 100644 --- a/include/zenoh-pico/api/primitives.h +++ b/include/zenoh-pico/api/primitives.h @@ -345,6 +345,19 @@ int8_t zp_config_insert(z_loaned_config_t *config, uint8_t key, const char *valu */ int8_t z_encoding_from_str(z_owned_encoding_t *encoding, const char *s); +/** + * Builds a :c:type:`z_owned_encoding_t` from a null terminated string. + * + * Parameters: + * encoding: Pointer to an uninitialized :c:type:`z_owned_encoding_t`. + * s: Pointer to the string to use. + * len: Number of characters from the string s to use. + * + * Return: + * ``0`` if creation successful,``negative value`` otherwise. + */ +int8_t z_encoding_from_substr(z_owned_encoding_t *encoding, const char *s, size_t len); + /** * Builds a string from a :c:type:`z_loaned_encoding_t`. * diff --git a/include/zenoh-pico/net/encoding.h b/include/zenoh-pico/net/encoding.h index 9c2899d6d..acd9061ec 100644 --- a/include/zenoh-pico/net/encoding.h +++ b/include/zenoh-pico/net/encoding.h @@ -27,7 +27,7 @@ typedef struct _z_encoding_t { uint16_t id; } _z_encoding_t; -int8_t _z_encoding_make(_z_encoding_t *encoding, uint16_t id, const char *schema); +int8_t _z_encoding_make(_z_encoding_t *encoding, uint16_t id, const char *schema, size_t len); _z_encoding_t _z_encoding_wrap(uint16_t id, const char *schema); _z_encoding_t _z_encoding_null(void); void _z_encoding_clear(_z_encoding_t *encoding); diff --git a/src/api/api.c b/src/api/api.c index 1446daa62..0dc1232a1 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -276,20 +276,23 @@ static uint16_t _z_encoding_values_str_to_int(const char *schema, size_t len) { return UINT16_MAX; } -static int8_t _z_encoding_convert_from_str(z_owned_encoding_t *encoding, const char *s) { - const char *id_end = strchr(s, ENCODING_SCHEMA_SEPARATOR); +static int8_t _z_encoding_convert_from_substr(z_owned_encoding_t *encoding, const char *s, size_t len) { + size_t pos = 0; + for (; pos < len; ++pos) { + if (s[pos] == ENCODING_SCHEMA_SEPARATOR) break; + } + // Check id_end value + corner cases - if ((id_end != NULL) && (id_end != s)) { - // Calc length of the segment before separator - size_t len = (size_t)(id_end - 1 - s); - uint16_t id = _z_encoding_values_str_to_int(s, len); + if ((pos != len) && (pos != 0)) { + uint16_t id = _z_encoding_values_str_to_int(s, pos); // Check id if (id != UINT16_MAX) { - return _z_encoding_make(&encoding->_val, id, (id_end[1] == '\0') ? NULL : ++id_end); + const char *ptr = (pos + 1 == len) ? NULL : s + pos + 1; + return _z_encoding_make(&encoding->_val, id, ptr, len - pos - 1); } } // By default store the string as schema - return _z_encoding_make(&encoding->_val, _Z_ENCODING_ID_DEFAULT, s); + return _z_encoding_make(&encoding->_val, _Z_ENCODING_ID_DEFAULT, s, len); } static int8_t _z_encoding_convert_into_string(const z_loaned_encoding_t *encoding, z_owned_string_t *s) { @@ -327,8 +330,8 @@ static int8_t _z_encoding_convert_into_string(const z_loaned_encoding_t *encodin } #else -static int8_t _z_encoding_convert_from_str(z_owned_encoding_t *encoding, const char *s) { - return _z_encoding_make(encoding->_val, _Z_ENCODING_ID_DEFAULT, s); +static int8_t _z_encoding_convert_from_substr(z_owned_encoding_t *encoding, const char *s, size_t len) { + return _z_encoding_make(encoding->_val, _Z_ENCODING_ID_DEFAULT, s, len); } static int8_t _z_encoding_convert_into_string(const z_loaned_encoding_t *encoding, z_owned_string_t *s) { @@ -346,7 +349,17 @@ int8_t z_encoding_from_str(z_owned_encoding_t *encoding, const char *s) { z_encoding_null(encoding); // Convert string to encoding if (s != NULL) { - return _z_encoding_convert_from_str(encoding, s); + return _z_encoding_convert_from_substr(encoding, s, strlen(s)); + } + return _Z_RES_OK; +} + +int8_t z_encoding_from_substr(z_owned_encoding_t *encoding, const char *s, size_t len) { + // Init owned encoding + z_encoding_null(encoding); + // Convert string to encoding + if (s != NULL) { + return _z_encoding_convert_from_substr(encoding, s, len); } return _Z_RES_OK; } diff --git a/src/net/encoding.c b/src/net/encoding.c index e09243a01..b3cecfd45 100644 --- a/src/net/encoding.c +++ b/src/net/encoding.c @@ -19,12 +19,12 @@ #include "zenoh-pico/utils/logging.h" #include "zenoh-pico/utils/result.h" -int8_t _z_encoding_make(_z_encoding_t *encoding, uint16_t id, const char *schema) { +int8_t _z_encoding_make(_z_encoding_t *encoding, uint16_t id, const char *schema, size_t len) { encoding->id = id; // Clone schema if (schema != NULL) { - encoding->schema = _z_string_make(schema); - if (encoding->schema.val == NULL) { + encoding->schema = _z_string_n_make(schema, len); + if (encoding->schema.len != len) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } } else { diff --git a/tests/z_api_encoding_test.c b/tests/z_api_encoding_test.c new file mode 100644 index 000000000..97157791f --- /dev/null +++ b/tests/z_api_encoding_test.c @@ -0,0 +1,82 @@ +#include +#include +#include + +#include "zenoh-pico/api/primitives.h" +#include "zenoh-pico/api/types.h" + +#undef NDEBUG +#include + +void test_null_encoding(void) { + z_owned_encoding_t e; + z_encoding_null(&e); + assert(!z_encoding_check(&e)); + z_encoding_drop(z_encoding_move(&e)); +} + +void test_encoding_without_id(void) { + z_owned_encoding_t e1; + z_encoding_from_str(&e1, "my_encoding"); + assert(z_encoding_check(&e1)); + z_owned_string_t s; + z_encoding_to_string(z_encoding_loan(&e1), &s); + assert(strncmp("zenoh/bytes;my_encoding", z_string_data(z_string_loan(&s)), z_string_len(z_string_loan(&s))) == 0); + z_encoding_drop(z_encoding_move(&e1)); + z_string_drop(z_string_move(&s)); + + z_owned_encoding_t e2; + z_encoding_from_substr(&e2, "my_encoding", 4); + assert(z_encoding_check(&e2)); + + z_encoding_to_string(z_encoding_loan(&e2), &s); + assert(strncmp("zenoh/bytes;my_e", z_string_data(z_string_loan(&s)), z_string_len(z_string_loan(&s))) == 0); + z_encoding_drop(z_encoding_move(&e2)); + z_string_drop(z_string_move(&s)); +} + +void test_encoding_with_id(void) { + z_owned_encoding_t e1; + z_encoding_from_str(&e1, "zenoh/string;utf8"); + assert(z_encoding_check(&e1)); + z_owned_string_t s; + z_encoding_to_string(z_encoding_loan(&e1), &s); + assert(strncmp("zenoh/string;utf8", z_string_data(z_string_loan(&s)), z_string_len(z_string_loan(&s))) == 0); + z_encoding_drop(z_encoding_move(&e1)); + z_string_drop(z_string_move(&s)); + + z_owned_encoding_t e2; + z_encoding_from_substr(&e2, "zenoh/string;utf8", 15); + assert(z_encoding_check(&e2)); + + z_encoding_to_string(z_encoding_loan(&e2), &s); + assert(strncmp("zenoh/string;utf8", z_string_data(z_string_loan(&s)), z_string_len(z_string_loan(&s))) == 0); + z_encoding_drop(z_encoding_move(&e2)); + z_string_drop(z_string_move(&s)); + + z_owned_encoding_t e3; + z_encoding_from_str(&e3, "custom_id;custom_schema"); + assert(z_encoding_check(&e3)); + + z_encoding_to_string(z_encoding_loan(&e3), &s); + assert(strncmp("zenoh/bytes;custom_id;custom_schema", z_string_data(z_string_loan(&s)), + z_string_len(z_string_loan(&s))) == 0); + z_encoding_drop(z_encoding_move(&e3)); + z_string_drop(z_string_move(&s)); + + z_owned_encoding_t e4; + z_encoding_from_substr(&e4, "custom_id;custom_schema", 16); + assert(z_encoding_check(&e2)); + + z_encoding_to_string(z_encoding_loan(&e4), &s); + assert(strncmp("zenoh/bytes;custom_id;custom", z_string_data(z_string_loan(&s)), z_string_len(z_string_loan(&s))) == + 0); + z_encoding_drop(z_encoding_move(&e4)); + z_string_drop(z_string_move(&s)); +} + +int main(void) { + test_null_encoding(); + test_encoding_without_id(); + test_encoding_with_id(); +}