From fd998225d53713d75a90907d6e287c958f470147 Mon Sep 17 00:00:00 2001 From: Jean-Roland Gosse Date: Fri, 23 Aug 2024 16:46:54 +0200 Subject: [PATCH] Switch keyexpr and locator to non null terminated strings (#602) * feat: add _z_string and _z_slice methods * feat: remove null-terminated from _z_string * feat: switch locators to _z_string * feat: switch _z_keyexpr to _z_string * fix: remove obsolete functions * tests: update tests without null terminated strings * feat: add _z_string_pbrk * fix: use _z_keyexpr_has_suffix * doc: remove functions from doc * feat: remove keyexpr_set_owns mechanism * feat: add z_string_from_substr * feat: remove obsolete functions * fix: canonizer * fix: use z_string_alias --- docs/api.rst | 5 - include/zenoh-pico/api/primitives.h | 71 ---- include/zenoh-pico/collections/slice.h | 2 + include/zenoh-pico/collections/string.h | 6 + include/zenoh-pico/config.h | 6 +- include/zenoh-pico/link/endpoint.h | 10 +- include/zenoh-pico/link/link.h | 4 +- include/zenoh-pico/net/primitives.h | 2 +- include/zenoh-pico/protocol/core.h | 23 +- include/zenoh-pico/protocol/keyexpr.h | 11 +- include/zenoh-pico/session/utils.h | 2 +- include/zenoh-pico/system/link/raweth.h | 2 +- include/zenoh-pico/transport/manager.h | 2 +- src/api/api.c | 177 ++++------ src/collections/slice.c | 22 +- src/collections/string.c | 80 ++++- src/link/endpoint.c | 419 +++++++++++----------- src/link/link.c | 8 +- src/link/multicast/udp.c | 49 +-- src/link/unicast/tcp.c | 45 ++- src/link/unicast/udp.c | 46 ++- src/link/unicast/ws.c | 23 +- src/net/primitives.c | 4 +- src/net/sample.c | 5 +- src/net/session.c | 8 +- src/protocol/codec/declarations.c | 32 +- src/protocol/codec/interest.c | 2 +- src/protocol/codec/message.c | 22 +- src/protocol/codec/network.c | 8 +- src/protocol/keyexpr.c | 94 +++-- src/session/interest.c | 18 +- src/session/query.c | 10 +- src/session/queryable.c | 8 +- src/session/resource.c | 64 ++-- src/session/scout.c | 9 +- src/session/subscription.c | 21 +- src/transport/manager.c | 6 +- src/transport/raweth/link.c | 24 +- src/transport/raweth/tx.c | 5 +- tests/z_api_alignment_test.c | 22 -- tests/z_client_test.c | 10 +- tests/z_endpoint_test.c | 146 +++----- tests/z_keyexpr_test.c | 448 ++++++++++-------------- tests/z_msgcodec_test.c | 43 ++- tests/z_peer_multicast_test.c | 1 - tests/z_test_fragment_rx.c | 6 +- tools/z_keyexpr_canonizer.c | 2 +- 47 files changed, 962 insertions(+), 1071 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 5b0e4bef1..1fea537d1 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -288,15 +288,10 @@ Primitives .. autocfunction:: primitives.h::z_view_keyexpr_from_str_autocanonize .. autocfunction:: primitives.h::z_keyexpr_as_view_string .. autocfunction:: primitives.h::z_keyexpr_is_canon -.. autocfunction:: primitives.h::zp_keyexpr_is_canon_null_terminated .. autocfunction:: primitives.h::z_keyexpr_canonize -.. autocfunction:: primitives.h::zp_keyexpr_canonize_null_terminated .. autocfunction:: primitives.h::z_keyexpr_includes -.. autocfunction:: primitives.h::zp_keyexpr_includes_null_terminated .. autocfunction:: primitives.h::z_keyexpr_intersects -.. autocfunction:: primitives.h::zp_keyexpr_intersect_null_terminated .. autocfunction:: primitives.h::z_keyexpr_equals -.. autocfunction:: primitives.h::zp_keyexpr_equals_null_terminated .. autocfunction:: primitives.h::z_keyexpr_relation_to .. autocfunction:: primitives.h::z_keyexpr_concat .. autocfunction:: primitives.h::z_keyexpr_join diff --git a/include/zenoh-pico/api/primitives.h b/include/zenoh-pico/api/primitives.h index fa63295e5..93dfa50ec 100644 --- a/include/zenoh-pico/api/primitives.h +++ b/include/zenoh-pico/api/primitives.h @@ -160,19 +160,6 @@ z_keyexpr_intersection_level_t z_keyexpr_relation_to(const z_loaned_keyexpr_t *l */ int8_t z_keyexpr_is_canon(const char *start, size_t len); -/** - * Checks if a given keyexpr is valid and in canonical form. - * - * Parameters: - * start: Pointer to the keyexpr in its string representation as a null terminated string. - * len: Number of characters in ``start``. - * - * Return: - * ``0`` if passed string is a valid (and canon) key expression, or a ``negative value`` otherwise. - * Error codes are defined in :c:enum:`zp_keyexpr_canon_status_t`. - */ -int8_t zp_keyexpr_is_canon_null_terminated(const char *start); - /** * Canonizes of a given keyexpr in string representation. * The canonization is performed over the passed string, possibly shortening it by modifying ``len``. @@ -187,20 +174,6 @@ int8_t zp_keyexpr_is_canon_null_terminated(const char *start); */ int8_t z_keyexpr_canonize(char *start, size_t *len); -/** - * Canonizes a given keyexpr in string representation. - * The canonization is performed over the passed string, possibly shortening it by modifying ``len``. - * - * Parameters: - * start: Pointer to the keyexpr in its string representation as a null terminated string. - * len: Number of characters in ``start``. - * - * Return: - * ``0`` if canonization successful, or a ``negative value`` otherwise. - * Error codes are defined in :c:enum:`zp_keyexpr_canon_status_t`. - */ -int8_t zp_keyexpr_canonize_null_terminated(char *start); - /** * Checks if a given keyexpr contains another keyexpr in its set. * @@ -214,21 +187,6 @@ int8_t zp_keyexpr_canonize_null_terminated(char *start); */ _Bool z_keyexpr_includes(const z_loaned_keyexpr_t *l, const z_loaned_keyexpr_t *r); -/** - * Checks if a given keyexpr contains another keyexpr in its set. - * - * Parameters: - * l: Pointer to the keyexpr in its string representation as a null terminated string. - * llen: Number of characters in ``l``. - * r: Pointer to the keyexpr in its string representation as a null terminated string. - * rlen: Number of characters in ``r``. - * - * Return: - * ``true`` if ``l`` includes ``r``, i.e. the set defined by ``l`` contains every key belonging to the set - * defined by ``r``. Otherwise, returns ``false``. - */ -_Bool zp_keyexpr_includes_null_terminated(const char *l, const char *r); - /** * Checks if a given keyexpr intersects with another keyexpr. * @@ -242,21 +200,6 @@ _Bool zp_keyexpr_includes_null_terminated(const char *l, const char *r); */ _Bool z_keyexpr_intersects(const z_loaned_keyexpr_t *l, const z_loaned_keyexpr_t *r); -/** - * Checks if a given keyexpr intersects with another keyexpr. - * - * Parameters: - * l: Pointer to the keyexpr in its string representation as a null terminated string. - * llen: Number of characters in ``l``. - * r: Pointer to the keyexpr in its string representation as a null terminated string. - * rlen: Number of characters in ``r``. - * - * Return: - * ``true`` if keyexprs intersect, i.e. there exists at least one key which is contained in both of the - * sets defined by ``l`` and ``r``. Otherwise, returns ``false``. - */ -_Bool zp_keyexpr_intersect_null_terminated(const char *l, const char *r); - /** * Checks if two keyexpr are equal. * @@ -269,20 +212,6 @@ _Bool zp_keyexpr_intersect_null_terminated(const char *l, const char *r); */ _Bool z_keyexpr_equals(const z_loaned_keyexpr_t *l, const z_loaned_keyexpr_t *r); -/** - * Checks if two keyexpr as null terminated string are equal. - * - * Parameters: - * l: Pointer to the keyexpr in its string representation as a null terminated string. - * llen: Number of characters in ``l``. - * r: Pointer to the keyexpr in its string representation as a null terminated string. - * rlen: Number of characters in ``r``. - * - * Return: - * ``true`` if both ``l`` and ``r`` are equal. Otherwise, it returns ``false``. - */ -_Bool zp_keyexpr_equals_null_terminated(const char *l, const char *r); - /** * Builds a new, zenoh-allocated, empty configuration. * It consists in an empty set of properties for zenoh session configuration. diff --git a/include/zenoh-pico/collections/slice.h b/include/zenoh-pico/collections/slice.h index fc880afcb..730b853f3 100644 --- a/include/zenoh-pico/collections/slice.h +++ b/include/zenoh-pico/collections/slice.h @@ -53,7 +53,9 @@ _z_slice_t _z_slice_from_buf(const uint8_t *bs, size_t len); _z_slice_t _z_slice_from_buf_custom_deleter(const uint8_t *p, size_t len, _z_delete_context_t dc); _z_slice_t _z_slice_copy_from_buf(const uint8_t *bs, size_t len); _z_slice_t _z_slice_steal(_z_slice_t *b); +_z_slice_t _z_slice_alias(const _z_slice_t *bs); int8_t _z_slice_copy(_z_slice_t *dst, const _z_slice_t *src); +int8_t _z_slice_n_copy(_z_slice_t *dst, const _z_slice_t *src, size_t offset, size_t len); _z_slice_t _z_slice_duplicate(const _z_slice_t *src); void _z_slice_move(_z_slice_t *dst, _z_slice_t *src); void _z_slice_reset(_z_slice_t *bs); diff --git a/include/zenoh-pico/collections/string.h b/include/zenoh-pico/collections/string.h index 9daf5d092..48d65e9ac 100644 --- a/include/zenoh-pico/collections/string.h +++ b/include/zenoh-pico/collections/string.h @@ -71,19 +71,25 @@ _Bool _z_string_check(const _z_string_t *value); _z_string_t _z_string_make(const char *value); _z_string_t _z_string_n_make(const char *value, size_t len); _z_string_t _z_string_from_str(const char *value); +_z_string_t _z_string_from_substr(const char *value, size_t len); _z_string_t _z_string_from_str_custom_deleter(char *value, _z_delete_context_t c); _z_string_t *_z_string_make_as_ptr(const char *value); _Bool _z_string_is_empty(const _z_string_t *s); +const char *_z_string_rchr(_z_string_t *str, char filter); +char *_z_string_pbrk(_z_string_t *str, const char *filter); size_t _z_string_len(const _z_string_t *s); const char *_z_string_data(const _z_string_t *s); int8_t _z_string_copy(_z_string_t *dst, const _z_string_t *src); +int8_t _z_string_copy_substring(_z_string_t *dst, const _z_string_t *src, size_t offset, size_t len); void _z_string_move(_z_string_t *dst, _z_string_t *src); _z_string_t _z_string_steal(_z_string_t *str); +_z_string_t _z_string_alias(const _z_string_t *str); void _z_string_move_str(_z_string_t *dst, char *src); void _z_string_clear(_z_string_t *s); void _z_string_free(_z_string_t **s); void _z_string_reset(_z_string_t *s); +_Bool _z_string_equals(const _z_string_t *left, const _z_string_t *right); _z_string_t _z_string_convert_bytes(const _z_slice_t *bs); _z_string_t _z_string_preallocate(const size_t len); diff --git a/include/zenoh-pico/config.h b/include/zenoh-pico/config.h index 3148545db..de3cb138e 100644 --- a/include/zenoh-pico/config.h +++ b/include/zenoh-pico/config.h @@ -16,9 +16,9 @@ #define INCLUDE_ZENOH_PICO_CONFIG_H /*--- CMake generated config; pass values to CMake to change the following tokens ---*/ -#define Z_FRAG_MAX_SIZE 4096 -#define Z_BATCH_UNICAST_SIZE 2048 -#define Z_BATCH_MULTICAST_SIZE 2048 +#define Z_FRAG_MAX_SIZE 300000 +#define Z_BATCH_UNICAST_SIZE 65535 +#define Z_BATCH_MULTICAST_SIZE 8096 #define Z_CONFIG_SOCKET_TIMEOUT 100 #define Z_FEATURE_MULTI_THREAD 1 diff --git a/include/zenoh-pico/link/endpoint.h b/include/zenoh-pico/link/endpoint.h index b855f961c..f9dd2efa3 100644 --- a/include/zenoh-pico/link/endpoint.h +++ b/include/zenoh-pico/link/endpoint.h @@ -42,15 +42,15 @@ #define LOCATOR_METADATA_SEPARATOR '?' typedef struct { _z_str_intmap_t _metadata; - char *_protocol; - char *_address; + _z_string_t _protocol; + _z_string_t _address; } _z_locator_t; _Bool _z_locator_eq(const _z_locator_t *left, const _z_locator_t *right); void _z_locator_init(_z_locator_t *locator); _z_string_t _z_locator_to_string(const _z_locator_t *loc); -int8_t _z_locator_from_str(_z_locator_t *lc, const char *s); +int8_t _z_locator_from_string(_z_locator_t *lc, _z_string_t *s); size_t _z_locator_size(_z_locator_t *lc); void _z_locator_clear(_z_locator_t *lc); @@ -67,8 +67,8 @@ typedef struct { _z_str_intmap_t _config; } _z_endpoint_t; -char *_z_endpoint_to_str(const _z_endpoint_t *e); -int8_t _z_endpoint_from_str(_z_endpoint_t *ep, const char *s); +_z_string_t _z_endpoint_to_string(const _z_endpoint_t *e); +int8_t _z_endpoint_from_string(_z_endpoint_t *ep, _z_string_t *s); void _z_endpoint_clear(_z_endpoint_t *ep); void _z_endpoint_free(_z_endpoint_t **ep); diff --git a/include/zenoh-pico/link/link.h b/include/zenoh-pico/link/link.h index fd4906daf..e4c83d78a 100644 --- a/include/zenoh-pico/link/link.h +++ b/include/zenoh-pico/link/link.h @@ -137,8 +137,8 @@ typedef struct _z_link_t { void _z_link_clear(_z_link_t *zl); void _z_link_free(_z_link_t **zl); -int8_t _z_open_link(_z_link_t *zl, const char *locator); -int8_t _z_listen_link(_z_link_t *zl, const char *locator); +int8_t _z_open_link(_z_link_t *zl, _z_string_t *locator); +int8_t _z_listen_link(_z_link_t *zl, _z_string_t *locator); int8_t _z_link_send_wbuf(const _z_link_t *zl, const _z_wbuf_t *wbf); size_t _z_link_recv_zbuf(const _z_link_t *zl, _z_zbuf_t *zbf, _z_slice_t *addr); diff --git a/include/zenoh-pico/net/primitives.h b/include/zenoh-pico/net/primitives.h index 308850a03..c3d610d11 100644 --- a/include/zenoh-pico/net/primitives.h +++ b/include/zenoh-pico/net/primitives.h @@ -37,7 +37,7 @@ * locator: The locator where to scout. * timeout: The time that should be spent scouting before returning the results. */ -void _z_scout(const z_what_t what, const _z_id_t zid, const char *locator, const uint32_t timeout, +void _z_scout(const z_what_t what, const _z_id_t zid, _z_string_t *locator, const uint32_t timeout, _z_hello_handler_t callback, void *arg_call, _z_drop_handler_t dropper, void *arg_drop); /*------------------ Declarations ------------------*/ diff --git a/include/zenoh-pico/protocol/core.h b/include/zenoh-pico/protocol/core.h index 1b2d5dcf8..78be5e3a7 100644 --- a/include/zenoh-pico/protocol/core.h +++ b/include/zenoh-pico/protocol/core.h @@ -87,25 +87,26 @@ typedef struct { #define _Z_KEYEXPR_MAPPING_UNKNOWN_REMOTE 0x7fff /** - * A zenoh-net resource key. + * A zenoh key-expression. * * Members: - * _z_zint_t: The resource ID. - * char *val: A pointer to the string containing the resource name. + * uint16_t _id: The resource ID of the ke. + * _z_mapping_t _mapping: The resource mapping of the ke. + * _z_string_t _suffix: The string value of the ke. */ typedef struct { uint16_t _id; _z_mapping_t _mapping; - char *_suffix; + _z_string_t _suffix; } _z_keyexpr_t; -static inline _Bool _z_keyexpr_owns_suffix(const _z_keyexpr_t *key) { return (key->_mapping._val & 0x8000) != 0; } + static inline uint16_t _z_keyexpr_mapping_id(const _z_keyexpr_t *key) { return key->_mapping._val & 0x7fff; } static inline _Bool _z_keyexpr_is_local(const _z_keyexpr_t *key) { return (key->_mapping._val & 0x7fff) == _Z_KEYEXPR_MAPPING_LOCAL; } -static inline _z_mapping_t _z_keyexpr_mapping(uint16_t id, _Bool owns_suffix) { +static inline _z_mapping_t _z_keyexpr_mapping(uint16_t id) { assert(id <= _Z_KEYEXPR_MAPPING_UNKNOWN_REMOTE); - _z_mapping_t mapping = {(uint16_t)((owns_suffix ? 0x8000 : 0) | id)}; + _z_mapping_t mapping = {id}; return mapping; } static inline void _z_keyexpr_set_mapping(_z_keyexpr_t *ke, uint16_t id) { @@ -118,12 +119,8 @@ static inline void _z_keyexpr_fix_mapping(_z_keyexpr_t *ke, uint16_t id) { _z_keyexpr_set_mapping(ke, id); } } -static inline void _z_keyexpr_set_owns_suffix(_z_keyexpr_t *ke, _Bool owns_suffix) { - ke->_mapping._val &= 0x7fff; - ke->_mapping._val |= owns_suffix ? 0x8000 : 0; -} -static inline _Bool _z_keyexpr_has_suffix(_z_keyexpr_t ke) { return (ke._suffix != NULL) && (ke._suffix[0] != 0); } -static inline _Bool _z_keyexpr_check(const _z_keyexpr_t *ke) { return (ke->_id != 0) || _z_keyexpr_has_suffix(*ke); } +static inline _Bool _z_keyexpr_has_suffix(const _z_keyexpr_t *ke) { return _z_string_check(&ke->_suffix); } +static inline _Bool _z_keyexpr_check(const _z_keyexpr_t *ke) { return (ke->_id != 0) || _z_keyexpr_has_suffix(ke); } /** * Create a resource key from a resource name. diff --git a/include/zenoh-pico/protocol/keyexpr.h b/include/zenoh-pico/protocol/keyexpr.h index ace9509e8..89f87b560 100644 --- a/include/zenoh-pico/protocol/keyexpr.h +++ b/include/zenoh-pico/protocol/keyexpr.h @@ -21,13 +21,14 @@ zp_keyexpr_canon_status_t _z_keyexpr_is_canon(const char *start, size_t len); zp_keyexpr_canon_status_t _z_keyexpr_canonize(char *start, size_t *len); -_Bool _z_keyexpr_includes(const char *lstart, const size_t llen, const char *rstart, const size_t rlen); -_Bool _z_keyexpr_intersects(const char *lstart, const size_t llen, const char *rstart, const size_t rlen); +_Bool _z_keyexpr_suffix_includes(const _z_keyexpr_t *left, const _z_keyexpr_t *right); +_Bool _z_keyexpr_suffix_intersects(const _z_keyexpr_t *left, const _z_keyexpr_t *right); +_Bool _z_keyexpr_suffix_equals(const _z_keyexpr_t *left, const _z_keyexpr_t *right); /*------------------ clone/Copy/Free helpers ------------------*/ +_z_keyexpr_t _z_keyexpr_from_string(uint16_t rid, _z_string_t *str); int8_t _z_keyexpr_copy(_z_keyexpr_t *dst, const _z_keyexpr_t *src); _z_keyexpr_t _z_keyexpr_duplicate(_z_keyexpr_t src); -_z_keyexpr_t _z_keyexpr_to_owned(_z_keyexpr_t src); _z_keyexpr_t _z_keyexpr_alias(_z_keyexpr_t src); /// Returns either keyexpr defined by id + mapping with null suffix if try_declared is true and id is non-zero, /// or keyexpr defined by its suffix only, with 0 id and no mapping. This is to be used only when forwarding @@ -35,9 +36,11 @@ _z_keyexpr_t _z_keyexpr_alias(_z_keyexpr_t src); _z_keyexpr_t _z_keyexpr_alias_from_user_defined(_z_keyexpr_t src, _Bool try_declared); _z_keyexpr_t _z_keyexpr_steal(_Z_MOVE(_z_keyexpr_t) src); static inline _z_keyexpr_t _z_keyexpr_null(void) { - _z_keyexpr_t keyexpr = {0, {0}, NULL}; + _z_keyexpr_t keyexpr = {0, {0}, _z_string_null()}; return keyexpr; } +_Bool _z_keyexpr_equals(const _z_keyexpr_t *left, const _z_keyexpr_t *right); +void _z_keyexpr_move(_z_keyexpr_t *dst, _z_keyexpr_t *src); void _z_keyexpr_clear(_z_keyexpr_t *rk); void _z_keyexpr_free(_z_keyexpr_t **rk); diff --git a/include/zenoh-pico/session/utils.h b/include/zenoh-pico/session/utils.h index 01650d65b..5e125556a 100644 --- a/include/zenoh-pico/session/utils.h +++ b/include/zenoh-pico/session/utils.h @@ -23,7 +23,7 @@ #include "zenoh-pico/protocol/core.h" /*------------------ Session ------------------*/ -_z_hello_list_t *_z_scout_inner(const z_what_t what, _z_id_t id, const char *locator, const uint32_t timeout, +_z_hello_list_t *_z_scout_inner(const z_what_t what, _z_id_t id, _z_string_t *locator, const uint32_t timeout, const _Bool exit_on_first); int8_t _z_session_init(_z_session_rc_t *zsrc, _z_id_t *zid); diff --git a/include/zenoh-pico/system/link/raweth.h b/include/zenoh-pico/system/link/raweth.h index c5be5be6a..af725a12b 100644 --- a/include/zenoh-pico/system/link/raweth.h +++ b/include/zenoh-pico/system/link/raweth.h @@ -32,7 +32,7 @@ // Max frame size #define _ZP_MAX_ETH_FRAME_SIZE 1514 -// Endpoing config types +// Endpoint config types typedef struct { _z_keyexpr_t _keyexpr; uint16_t _vlan; // vlan tag (pcp + dei + id), big endian diff --git a/include/zenoh-pico/transport/manager.h b/include/zenoh-pico/transport/manager.h index f817c2494..6a6a7ad48 100644 --- a/include/zenoh-pico/transport/manager.h +++ b/include/zenoh-pico/transport/manager.h @@ -19,7 +19,7 @@ #include "zenoh-pico/link/manager.h" #include "zenoh-pico/transport/transport.h" -int8_t _z_new_transport(_z_transport_t *zt, _z_id_t *bs, char *locator, z_whatami_t mode); +int8_t _z_new_transport(_z_transport_t *zt, _z_id_t *bs, _z_string_t *locator, z_whatami_t mode); void _z_free_transport(_z_transport_t **zt); #endif /* INCLUDE_ZENOH_PICO_TRANSPORT_MANAGER_H */ diff --git a/src/api/api.c b/src/api/api.c index 53948ac93..009e8d5aa 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -42,6 +42,7 @@ #include "zenoh-pico/transport/unicast.h" #include "zenoh-pico/utils/endianness.h" #include "zenoh-pico/utils/logging.h" +#include "zenoh-pico/utils/pointers.h" #include "zenoh-pico/utils/result.h" #include "zenoh-pico/utils/uuid.h" @@ -60,18 +61,9 @@ size_t z_string_array_len(const z_loaned_string_array_t *a) { return _z_string_s _Bool z_string_array_is_empty(const z_loaned_string_array_t *a) { return _z_string_svec_is_empty(a); } -int8_t zp_keyexpr_canonize_null_terminated(char *start) { - zp_keyexpr_canon_status_t ret = Z_KEYEXPR_CANON_SUCCESS; - - size_t len = strlen(start); - size_t newlen = len; - ret = _z_keyexpr_canonize(start, &newlen); - if (newlen < len) { - start[newlen] = '\0'; - } +int8_t z_keyexpr_is_canon(const char *start, size_t len) { return _z_keyexpr_is_canon(start, len); } - return ret; -} +int8_t z_keyexpr_canonize(char *start, size_t *len) { return _z_keyexpr_canonize(start, len); } int8_t z_view_keyexpr_from_str(z_view_keyexpr_t *keyexpr, const char *name) { keyexpr->_val = _z_rname(name); @@ -79,8 +71,10 @@ int8_t z_view_keyexpr_from_str(z_view_keyexpr_t *keyexpr, const char *name) { } int8_t z_view_keyexpr_from_str_autocanonize(z_view_keyexpr_t *keyexpr, char *name) { - _Z_RETURN_IF_ERR(zp_keyexpr_canonize_null_terminated(name)); - keyexpr->_val = _z_rname(name); + size_t name_len = strlen(name); + _Z_RETURN_IF_ERR(z_keyexpr_canonize(name, &name_len)); + keyexpr->_val = _z_rname(NULL); + keyexpr->_val._suffix = _z_string_from_substr(name, name_len); return _Z_RES_OK; } @@ -90,7 +84,7 @@ int8_t z_view_keyexpr_from_str_unchecked(z_view_keyexpr_t *keyexpr, const char * } int8_t z_keyexpr_as_view_string(const z_loaned_keyexpr_t *keyexpr, z_view_string_t *s) { - s->_val = _z_string_from_str(keyexpr->_suffix); + s->_val = _z_string_alias(&keyexpr->_suffix); return _Z_RES_OK; } @@ -101,46 +95,43 @@ int8_t z_keyexpr_concat(z_owned_keyexpr_t *key, const z_loaned_keyexpr_t *left, } else if (right == NULL) { return _Z_ERR_INVALID; } - size_t left_len = strlen(left->_suffix); + size_t left_len = _z_string_len(&left->_suffix); if (left_len == 0) { return _Z_ERR_INVALID; } - if (left->_suffix[left_len - 1] == '*' && right[0] == '*') { + const char *left_data = _z_string_data(&left->_suffix); + + if (left_data[left_len - 1] == '*' && right[0] == '*') { return _Z_ERR_INVALID; } - char *s = z_malloc(left_len + len + 1); - if (s == NULL) { + key->_val._suffix = _z_string_preallocate(left_len + len); + if (!_z_keyexpr_has_suffix(&key->_val)) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } - s[left_len + len] = '\0'; - - memcpy(s, left->_suffix, left_len); - memcpy(s + left_len, right, len); - - key->_val = _z_rname(s); - _z_keyexpr_set_owns_suffix(&key->_val, true); + // Copy data + uint8_t *curr_ptr = (uint8_t *)_z_string_data(&key->_val._suffix); + memcpy(curr_ptr, _z_string_data(&left->_suffix), left_len); + memcpy(curr_ptr + left_len, right, len); return _Z_RES_OK; } int8_t z_keyexpr_join(z_owned_keyexpr_t *key, const z_loaned_keyexpr_t *left, const z_loaned_keyexpr_t *right) { z_internal_keyexpr_null(key); - size_t left_len = strlen(left->_suffix); - size_t right_len = strlen(right->_suffix); + size_t left_len = _z_string_len(&left->_suffix); + size_t right_len = _z_string_len(&right->_suffix); - char *s = z_malloc(left_len + right_len + 2); - if (s == NULL) { + key->_val._suffix = _z_string_preallocate(left_len + right_len + 1); + if (!_z_keyexpr_has_suffix(&key->_val)) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } - s[left_len + right_len + 1] = '\0'; - s[left_len] = '/'; - memcpy(s, left->_suffix, left_len); - memcpy(s + left_len + 1, right->_suffix, right_len); - - _Z_CLEAN_RETURN_IF_ERR(zp_keyexpr_canonize_null_terminated(s), z_free(s)); - key->_val = _z_rname(s); - _z_keyexpr_set_owns_suffix(&key->_val, true); + // Copy data + uint8_t *curr_ptr = (uint8_t *)_z_string_data(&key->_val._suffix); + memcpy(curr_ptr, _z_string_data(&left->_suffix), left_len); + curr_ptr[left_len] = '/'; + memcpy(curr_ptr + left_len + 1, _z_string_data(&right->_suffix), right_len); + _Z_CLEAN_RETURN_IF_ERR(z_keyexpr_canonize((char *)curr_ptr, &key->_val._suffix._slice.len), z_free(curr_ptr)); return _Z_RES_OK; } @@ -155,48 +146,16 @@ z_keyexpr_intersection_level_t z_keyexpr_relation_to(const z_loaned_keyexpr_t *l return Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT; } -int8_t z_keyexpr_is_canon(const char *start, size_t len) { return _z_keyexpr_is_canon(start, len); } - -int8_t zp_keyexpr_is_canon_null_terminated(const char *start) { return _z_keyexpr_is_canon(start, strlen(start)); } - -int8_t z_keyexpr_canonize(char *start, size_t *len) { return _z_keyexpr_canonize(start, len); } - _Bool z_keyexpr_includes(const z_loaned_keyexpr_t *l, const z_loaned_keyexpr_t *r) { - return zp_keyexpr_includes_null_terminated(l->_suffix, r->_suffix); -} - -_Bool zp_keyexpr_includes_null_terminated(const char *l, const char *r) { - if (l != NULL && r != NULL) { - return _z_keyexpr_includes(l, strlen(l), r, strlen(r)); - } - return false; + return _z_keyexpr_suffix_includes(l, r); } _Bool z_keyexpr_intersects(const z_loaned_keyexpr_t *l, const z_loaned_keyexpr_t *r) { - return zp_keyexpr_intersect_null_terminated(l->_suffix, r->_suffix); -} - -_Bool zp_keyexpr_intersect_null_terminated(const char *l, const char *r) { - if (l != NULL && r != NULL) { - return _z_keyexpr_intersects(l, strlen(l), r, strlen(r)); - } - return false; + return _z_keyexpr_suffix_intersects(l, r); } _Bool z_keyexpr_equals(const z_loaned_keyexpr_t *l, const z_loaned_keyexpr_t *r) { - return zp_keyexpr_equals_null_terminated(l->_suffix, r->_suffix); -} - -_Bool zp_keyexpr_equals_null_terminated(const char *l, const char *r) { - if (l != NULL && r != NULL) { - size_t llen = strlen(l); - if (llen == strlen(r)) { - if (strncmp(l, r, llen) == 0) { - return true; - } - } - } - return false; + return _z_keyexpr_suffix_equals(l, r); } void z_config_new(z_owned_config_t *config) { config->_val = _z_config_empty(); } @@ -886,7 +845,7 @@ int8_t z_scout(z_moved_config_t *config, z_moved_closure_hello_t *callback, cons if (opt_as_str == NULL) { opt_as_str = (char *)Z_CONFIG_MULTICAST_LOCATOR_DEFAULT; } - char *mcast_locator = opt_as_str; + _z_string_t mcast_locator = _z_string_from_str(opt_as_str); uint32_t timeout; if (options != NULL) { @@ -905,7 +864,7 @@ int8_t z_scout(z_moved_config_t *config, z_moved_closure_hello_t *callback, cons _z_uuid_to_bytes(zid.id, zid_str); } - _z_scout(what, zid, mcast_locator, timeout, __z_hello_handler, wrapped_ctx, callback->_this._val.drop, ctx); + _z_scout(what, zid, &mcast_locator, timeout, __z_hello_handler, wrapped_ctx, callback->_this._val.drop, ctx); z_free(wrapped_ctx); z_config_drop(config); @@ -1143,7 +1102,7 @@ int8_t z_declare_publisher(z_owned_publisher_t *pub, const z_loaned_session_t *z _z_resource_t *r = _z_get_resource_by_key(_Z_RC_IN_VAL(zs), &keyexpr_aliased); if (r == NULL) { uint16_t id = _z_declare_resource(_Z_RC_IN_VAL(zs), keyexpr_aliased); - key = _z_rid_with_suffix(id, keyexpr_aliased._suffix); + key = _z_keyexpr_from_string(id, &keyexpr_aliased._suffix); } } // Set options @@ -1197,7 +1156,7 @@ int8_t z_publisher_put(const z_loaned_publisher_t *pub, z_moved_bytes_t *payload // Remove potentially redundant ke suffix _z_keyexpr_t pub_keyexpr = _z_keyexpr_alias(pub->_key); if (pub_keyexpr._id != Z_RESOURCE_ID_NONE) { - pub_keyexpr._suffix = NULL; + pub_keyexpr._suffix = _z_string_null(); } // Check if write filter is active before writing @@ -1229,7 +1188,7 @@ int8_t z_publisher_delete(const z_loaned_publisher_t *pub, const z_publisher_del // Remove potentially redundant ke suffix _z_keyexpr_t pub_keyexpr = _z_keyexpr_alias(pub->_key); if (pub_keyexpr._id != Z_RESOURCE_ID_NONE) { - pub_keyexpr._suffix = NULL; + pub_keyexpr._suffix = _z_string_null(); } return _z_write(_Z_RC_IN_VAL(&pub->_zn), pub_keyexpr, _z_bytes_null(), NULL, Z_SAMPLE_KIND_DELETE, @@ -1488,15 +1447,18 @@ int8_t z_keyexpr_from_str_autocanonize(z_owned_keyexpr_t *key, const char *name) int8_t z_keyexpr_from_substr_autocanonize(z_owned_keyexpr_t *key, const char *name, size_t *len) { z_internal_keyexpr_null(key); - char *name_copy = _z_str_n_clone(name, *len); - if (name_copy == NULL) { + + // Copy the suffix + key->_val._suffix = _z_string_preallocate(*len); + if (!_z_keyexpr_has_suffix(&key->_val)) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } - - _Z_CLEAN_RETURN_IF_ERR(z_keyexpr_canonize(name_copy, len), z_free(name_copy)); - name_copy[*len] = '\0'; - key->_val = _z_rname(name_copy); - _z_keyexpr_set_owns_suffix(&key->_val, true); + memcpy((char *)_z_string_data(&key->_val._suffix), name, _z_string_len(&key->_val._suffix)); + // Canonize the suffix + _Z_CLEAN_RETURN_IF_ERR( + z_keyexpr_canonize((char *)_z_string_data(&key->_val._suffix), &key->_val._suffix._slice.len), + _z_keyexpr_clear(&key->_val)); + *len = _z_string_len(&key->_val._suffix); return _Z_RES_OK; } @@ -1506,12 +1468,11 @@ int8_t z_keyexpr_from_str(z_owned_keyexpr_t *key, const char *name) { int8_t z_keyexpr_from_substr(z_owned_keyexpr_t *key, const char *name, size_t len) { z_internal_keyexpr_null(key); - char *name_copy = _z_str_n_clone(name, len); - if (name_copy == NULL) { + key->_val._suffix = _z_string_preallocate(len); + if (!_z_keyexpr_has_suffix(&key->_val)) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } - key->_val = _z_rname(name_copy); - _z_keyexpr_set_owns_suffix(&key->_val, true); + memcpy((char *)_z_string_data(&key->_val._suffix), name, _z_string_len(&key->_val._suffix)); return _Z_RES_OK; } @@ -1519,18 +1480,14 @@ int8_t z_declare_keyexpr(z_owned_keyexpr_t *key, const z_loaned_session_t *zs, c _z_keyexpr_t k = _z_keyexpr_alias_from_user_defined(*keyexpr, false); uint16_t id = _z_declare_resource(_Z_RC_IN_VAL(zs), k); key->_val = _z_rid_with_suffix(id, NULL); - if (keyexpr->_suffix) { - key->_val._suffix = _z_str_clone(keyexpr->_suffix); - } // we still need to store the original suffix, for user needs // (for example to compare keys or perform other operations on their string representation). // Generally this breaks internal keyexpr representation, but is ok for user-defined keyexprs // since they consist of 2 disjoint sets: either they have a non-nul suffix or non-trivial id/mapping. // The resulting keyexpr can be separated later into valid internal keys using _z_keyexpr_alias_from_user_defined. - if (key->_val._suffix == NULL && keyexpr->_suffix != NULL) { - return _Z_ERR_SYSTEM_OUT_OF_MEMORY; + if (_z_keyexpr_has_suffix(keyexpr)) { + _Z_RETURN_IF_ERR(_z_string_copy(&key->_val._suffix, &keyexpr->_suffix)); } - _z_keyexpr_set_owns_suffix(&key->_val, true); return _Z_RES_OK; } @@ -1568,10 +1525,9 @@ int8_t z_declare_subscriber(z_owned_subscriber_t *sub, const z_loaned_session_t z_moved_closure_sample_t *callback, const z_subscriber_options_t *options) { void *ctx = callback->_this._val.context; callback->_this._val.context = NULL; - char *suffix = NULL; _z_keyexpr_t keyexpr_aliased = _z_keyexpr_alias_from_user_defined(*keyexpr, true); - _z_keyexpr_t key = keyexpr_aliased; + _z_keyexpr_t key = _z_keyexpr_alias(keyexpr_aliased); // TODO: Currently, if resource declarations are done over multicast transports, the current protocol definition // lacks a way to convey them to later-joining nodes. Thus, in the current version automatic @@ -1579,22 +1535,21 @@ int8_t z_declare_subscriber(z_owned_subscriber_t *sub, const z_loaned_session_t if (_Z_RC_IN_VAL(zs)->_tp._type == _Z_TRANSPORT_UNICAST_TYPE) { _z_resource_t *r = _z_get_resource_by_key(_Z_RC_IN_VAL(zs), &keyexpr_aliased); if (r == NULL) { - char *wild = strpbrk(keyexpr_aliased._suffix, "*$"); _Bool do_keydecl = true; - _z_keyexpr_t resource_key = keyexpr_aliased; - if (wild != NULL && wild != resource_key._suffix) { - wild -= 1; - size_t len = (size_t)(wild - resource_key._suffix); - suffix = z_malloc(len + 1); - if (suffix != NULL) { - memcpy(suffix, resource_key._suffix, len); - suffix[len] = 0; - resource_key._suffix = suffix; - _z_keyexpr_set_owns_suffix(&resource_key, false); - } else { - do_keydecl = false; + _z_keyexpr_t resource_key = _z_keyexpr_alias(keyexpr_aliased); + // Remove wild + char *wild = _z_string_pbrk(&keyexpr_aliased._suffix, "*$"); + if ((wild != NULL) && _z_keyexpr_has_suffix(&keyexpr_aliased)) { + wild = _z_ptr_char_offset(wild, -1); + size_t len = _z_ptr_char_diff(wild, _z_string_data(&keyexpr_aliased._suffix)); + resource_key._suffix = _z_string_preallocate(len); + + if (!_z_keyexpr_has_suffix(&resource_key)) { + return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } + memcpy((char *)_z_string_data(&resource_key._suffix), _z_string_data(&keyexpr_aliased._suffix), len); } + // Declare resource if (do_keydecl) { uint16_t id = _z_declare_resource(_Z_RC_IN_VAL(zs), resource_key); key = _z_rid_with_suffix(id, wild); @@ -1613,9 +1568,7 @@ int8_t z_declare_subscriber(z_owned_subscriber_t *sub, const z_loaned_session_t } _z_subscriber_t int_sub = _z_declare_subscriber(zs, key, subinfo, callback->_this._val.call, callback->_this._val.drop, ctx); - if (suffix != NULL) { - z_free(suffix); - } + z_internal_closure_sample_null(&callback->_this); sub->_val = int_sub; diff --git a/src/collections/slice.c b/src/collections/slice.c index 903d614a0..d2db78030 100644 --- a/src/collections/slice.c +++ b/src/collections/slice.c @@ -14,11 +14,13 @@ #include "zenoh-pico/collections/slice.h" +#include #include #include #include "zenoh-pico/system/platform.h" #include "zenoh-pico/utils/endianness.h" +#include "zenoh-pico/utils/pointers.h" #include "zenoh-pico/utils/result.h" void _z_default_deleter(void *data, void *context) { @@ -80,6 +82,11 @@ _z_slice_t _z_slice_from_buf_custom_deleter(const uint8_t *p, size_t len, _z_del return bs; } +_z_slice_t _z_slice_alias(const _z_slice_t *bs) { + _z_slice_t alias = {.len = bs->len, .start = bs->start, ._delete_context = _z_delete_context_null()}; + return alias; +} + _z_slice_t _z_slice_from_buf(const uint8_t *p, size_t len) { return _z_slice_from_buf_custom_deleter(p, len, _z_delete_context_null()); } @@ -114,14 +121,25 @@ void _z_slice_free(_z_slice_t **bs) { } int8_t _z_slice_copy(_z_slice_t *dst, const _z_slice_t *src) { - int8_t ret = - _z_slice_init(dst, src->len); // FIXME: it should check if dst is already initialized. Otherwise it will leak + // Make sure dst slice is not init beforehand, or suffer memory leak + int8_t ret = _z_slice_init(dst, src->len); if (ret == _Z_RES_OK) { (void)memcpy((uint8_t *)dst->start, src->start, src->len); } return ret; } +int8_t _z_slice_n_copy(_z_slice_t *dst, const _z_slice_t *src, size_t offset, size_t len) { + assert(offset + len <= src->len); + // Make sure dst slice is not init beforehand, or suffer memory leak + int8_t ret = _z_slice_init(dst, len); + if (ret == _Z_RES_OK) { + const uint8_t *start = _z_cptr_u8_offset(src->start, (ptrdiff_t)offset); + (void)memcpy((uint8_t *)dst->start, start, len); + } + return ret; +} + void _z_slice_move(_z_slice_t *dst, _z_slice_t *src) { dst->start = src->start; dst->len = src->len; diff --git a/src/collections/string.c b/src/collections/string.c index 024b385db..0a4b08314 100644 --- a/src/collections/string.c +++ b/src/collections/string.c @@ -17,6 +17,8 @@ #include #include +#include "zenoh-pico/utils/pointers.h" + /*-------- string --------*/ _z_string_t _z_string_null(void) { _z_string_t s = {._slice = _z_slice_empty()}; @@ -27,7 +29,7 @@ _Bool _z_string_check(const _z_string_t *value) { return !_z_slice_is_empty(&val _z_string_t _z_string_make(const char *value) { _z_string_t s; - s._slice = _z_slice_copy_from_buf((uint8_t *)value, strlen(value) + 1); + s._slice = _z_slice_copy_from_buf((uint8_t *)value, strlen(value)); return s; } @@ -38,20 +40,26 @@ _z_string_t _z_string_n_make(const char *value, size_t len) { if (c == NULL) { return _z_string_null(); } else { - s._slice = _z_slice_from_buf_custom_deleter((const uint8_t *)c, len + 1, _z_delete_context_default()); + s._slice = _z_slice_from_buf_custom_deleter((const uint8_t *)c, len, _z_delete_context_default()); return s; } } _z_string_t _z_string_from_str(const char *value) { _z_string_t s; - s._slice = _z_slice_from_buf((const uint8_t *)(value), strlen(value) + 1); + s._slice = _z_slice_from_buf((const uint8_t *)(value), strlen(value)); + return s; +} + +_z_string_t _z_string_from_substr(const char *value, size_t len) { + _z_string_t s; + s._slice = _z_slice_from_buf((const uint8_t *)(value), len); return s; } _z_string_t _z_string_from_str_custom_deleter(char *value, _z_delete_context_t c) { _z_string_t s; - s._slice = _z_slice_from_buf_custom_deleter((const uint8_t *)(value), strlen(value) + 1, c); + s._slice = _z_slice_from_buf_custom_deleter((const uint8_t *)(value), strlen(value), c); return s; } @@ -65,10 +73,14 @@ _z_string_t *_z_string_make_as_ptr(const char *value) { return s; } -size_t _z_string_len(const _z_string_t *s) { return s->_slice.len == 0 ? 0 : s->_slice.len - 1; } +size_t _z_string_len(const _z_string_t *s) { return s->_slice.len; } int8_t _z_string_copy(_z_string_t *dst, const _z_string_t *src) { return _z_slice_copy(&dst->_slice, &src->_slice); } +int8_t _z_string_copy_substring(_z_string_t *dst, const _z_string_t *src, size_t offset, size_t len) { + return _z_slice_n_copy(&dst->_slice, &src->_slice, offset, len); +} + void _z_string_move(_z_string_t *dst, _z_string_t *src) { *dst = _z_string_steal(src); } _z_string_t _z_string_steal(_z_string_t *str) { @@ -77,6 +89,11 @@ _z_string_t _z_string_steal(_z_string_t *str) { return ret; } +_z_string_t _z_string_alias(const _z_string_t *str) { + _z_string_t alias = {._slice = _z_slice_alias(&str->_slice)}; + return alias; +} + void _z_string_move_str(_z_string_t *dst, char *src) { *dst = _z_string_from_str(src); } void _z_string_reset(_z_string_t *str) { _z_slice_reset(&str->_slice); } @@ -93,10 +110,17 @@ void _z_string_free(_z_string_t **str) { } } +_Bool _z_string_equals(const _z_string_t *left, const _z_string_t *right) { + if (_z_string_len(left) != _z_string_len(right)) { + return false; + } + return (strncmp(_z_string_data(left), _z_string_data(right), _z_string_len(left)) == 0); +} + _z_string_t _z_string_convert_bytes(const _z_slice_t *bs) { _z_string_t s = _z_string_null(); size_t len = bs->len * (size_t)2; - char *s_val = (char *)z_malloc((len + (size_t)1) * sizeof(char)); + char *s_val = (char *)z_malloc((len) * sizeof(char)); if (s_val == NULL) { return s; } @@ -105,30 +129,62 @@ _z_string_t _z_string_convert_bytes(const _z_slice_t *bs) { const char c[] = "0123456789ABCDEF"; for (size_t i = 0; i < bs->len; i++) { s_val[i * (size_t)2] = c[(bs->start[i] & (uint8_t)0xF0) >> (uint8_t)4]; - s_val[(i * (size_t)2) + (size_t)1] = c[bs->start[i] & (uint8_t)0x0F]; + s_val[(i * (size_t)2)] = c[bs->start[i] & (uint8_t)0x0F]; } - s_val[len] = '\0'; } else { len = 0; } - s._slice = _z_slice_from_buf_custom_deleter((const uint8_t *)s_val, len + 1, _z_delete_context_default()); + s._slice = _z_slice_from_buf_custom_deleter((const uint8_t *)s_val, len, _z_delete_context_default()); return s; } _z_string_t _z_string_preallocate(size_t len) { _z_string_t s = _z_string_null(); - _z_slice_init(&s._slice, len + 1); + _z_slice_init(&s._slice, len); if (_z_slice_is_empty(&s._slice)) { return _z_string_null(); } - char *ss = (char *)s._slice.start; - ss[len] = '\0'; return s; } const char *_z_string_data(const _z_string_t *s) { return (const char *)s->_slice.start; } _Bool _z_string_is_empty(const _z_string_t *s) { return s->_slice.len <= 1; } + +const char *_z_string_rchr(_z_string_t *str, char filter) { + const char *curr_res = NULL; + const char *ret = NULL; + const char *curr_addr = _z_string_data(str); + size_t curr_len = _z_string_len(str); + do { + curr_res = (char *)memchr(curr_addr, (int)filter, curr_len); + if (curr_res != NULL) { + ret = curr_res; + curr_addr = curr_res + 1; + curr_len = _z_ptr_char_diff(curr_addr, _z_string_data(str)); + if (curr_len >= _z_string_len(str)) { + break; + } + curr_len = _z_string_len(str) - curr_len; + } + } while (curr_res != NULL); + return ret; +} + +char *_z_string_pbrk(_z_string_t *str, const char *filter) { + const char *data = _z_string_data(str); + for (size_t idx = 0; idx < _z_string_len(str); idx++) { + const char *curr_char = filter; + while (*curr_char != '\0') { + if (data[idx] == *curr_char) { + return (char *)&data[idx]; + } + curr_char++; + } + } + return NULL; +} + /*-------- str --------*/ size_t _z_str_size(const char *src) { return strlen(src) + (size_t)1; } diff --git a/src/link/endpoint.c b/src/link/endpoint.c index 3af04d885..317c0b529 100644 --- a/src/link/endpoint.c +++ b/src/link/endpoint.c @@ -19,6 +19,7 @@ #include #include "zenoh-pico/config.h" +#include "zenoh-pico/utils/logging.h" #include "zenoh-pico/utils/pointers.h" #if Z_FEATURE_LINK_TCP == 1 #include "zenoh-pico/link/config/tcp.h" @@ -39,14 +40,14 @@ /*------------------ Locator ------------------*/ void _z_locator_init(_z_locator_t *locator) { - locator->_protocol = NULL; - locator->_address = NULL; + locator->_protocol = _z_string_null(); + locator->_address = _z_string_null(); locator->_metadata = _z_str_intmap_make(); } void _z_locator_clear(_z_locator_t *lc) { - _z_str_free(&lc->_protocol); - _z_str_free(&lc->_address); + _z_string_clear(&lc->_protocol); + _z_string_clear(&lc->_address); _z_str_intmap_clear(&lc->_metadata); } @@ -61,20 +62,21 @@ void _z_locator_free(_z_locator_t **lc) { } } -void _z_locator_copy(_z_locator_t *dst, const _z_locator_t *src) { - dst->_protocol = _z_str_clone(src->_protocol); - dst->_address = _z_str_clone(src->_address); +int8_t _z_locator_copy(_z_locator_t *dst, const _z_locator_t *src) { + _Z_RETURN_IF_ERR(_z_string_copy(&dst->_protocol, &src->_protocol)); + _Z_RETURN_IF_ERR(_z_string_copy(&dst->_address, &src->_address)); // @TODO: implement copy for metadata dst->_metadata = _z_str_intmap_make(); + return _Z_RES_OK; } _Bool _z_locator_eq(const _z_locator_t *left, const _z_locator_t *right) { _Bool res = false; - res = _z_str_eq(left->_protocol, right->_protocol); + res = _z_string_equals(&left->_protocol, &right->_protocol); if (res == true) { - res = _z_str_eq(left->_address, right->_address); + res = _z_string_equals(&left->_address, &right->_address); // if (res == true) { // // @TODO: implement eq for metadata // } @@ -83,71 +85,78 @@ _Bool _z_locator_eq(const _z_locator_t *left, const _z_locator_t *right) { return res; } -char *_z_locator_protocol_from_str(const char *str) { - char *ret = NULL; - - if (str != NULL) { - const char *p_start = &str[0]; - const char *p_end = strchr(p_start, LOCATOR_PROTOCOL_SEPARATOR); - if ((p_end != NULL) && (p_start != p_end)) { - size_t p_len = _z_ptr_char_diff(p_end, p_start) + (size_t)1; - ret = (char *)z_malloc(p_len); - if (ret != NULL) { - _z_str_n_copy(ret, p_start, p_len); - } - } - } +static int8_t _z_locator_protocol_from_string(_z_string_t *protocol, _z_string_t *str) { + *protocol = _z_string_null(); - return ret; + const char *p_start = _z_string_data(str); + const char *p_end = (char *)memchr(p_start, (int)LOCATOR_PROTOCOL_SEPARATOR, _z_string_len(str)); + if ((p_end == NULL) || (p_start == p_end)) { + return _Z_ERR_CONFIG_LOCATOR_INVALID; + } + size_t p_len = _z_ptr_char_diff(p_end, p_start); + return _z_string_copy_substring(protocol, str, 0, p_len); } -char *_z_locator_address_from_str(const char *str) { - char *ret = NULL; - - const char *p_start = strchr(str, LOCATOR_PROTOCOL_SEPARATOR); - if (p_start != NULL) { - p_start = _z_cptr_char_offset(p_start, 1); // Skip protocol separator character - - const char *p_end = strchr(p_start, LOCATOR_METADATA_SEPARATOR); - if (p_end == NULL) { // There is no metadata separator, then look for config separator - p_end = strchr(p_start, ENDPOINT_CONFIG_SEPARATOR); - } - if (p_end == NULL) { // There is no config separator, then address goes to the end of string - p_end = &str[strlen(str)]; - } +static int8_t _z_locator_address_from_string(_z_string_t *address, _z_string_t *str) { + *address = _z_string_null(); - if (p_start != p_end) { - size_t a_len = _z_ptr_char_diff(p_end, p_start) + (size_t)1; - ret = (char *)z_malloc(a_len); - if (ret != NULL) { - _z_str_n_copy(ret, p_start, a_len); - } - } + // Find protocol separator + const char *p_start = (char *)memchr(_z_string_data(str), (int)LOCATOR_PROTOCOL_SEPARATOR, _z_string_len(str)); + if (p_start == NULL) { + return _Z_ERR_CONFIG_LOCATOR_INVALID; } - - return ret; + // Skip protocol separator + p_start = _z_cptr_char_offset(p_start, 1); + size_t start_offset = _z_ptr_char_diff(p_start, _z_string_data(str)); + if (start_offset >= _z_string_len(str)) { + return _Z_ERR_CONFIG_LOCATOR_INVALID; + } + // Find metadata separator + size_t curr_len = _z_string_len(str) - start_offset; + const char *p_end = (char *)memchr(p_start, (int)LOCATOR_METADATA_SEPARATOR, curr_len); + // There is no metadata separator, then look for config separator + if (p_end == NULL) { + p_end = memchr(p_start, (int)ENDPOINT_CONFIG_SEPARATOR, curr_len); + } + // There is no config separator, then address goes to the end of string + if (p_end == NULL) { + p_end = _z_cptr_char_offset(_z_string_data(str), (ptrdiff_t)_z_string_len(str)); + } + if (p_start >= p_end) { + return _Z_ERR_CONFIG_LOCATOR_INVALID; + } + // Copy data + size_t addr_len = _z_ptr_char_diff(p_end, p_start); + return _z_string_copy_substring(address, str, start_offset, addr_len); } -int8_t _z_locator_metadata_from_str(_z_str_intmap_t *strint, const char *str) { - int8_t ret = _Z_RES_OK; +int8_t _z_locator_metadata_from_string(_z_str_intmap_t *strint, _z_string_t *str) { *strint = _z_str_intmap_make(); - const char *p_start = strchr(str, LOCATOR_METADATA_SEPARATOR); - if (p_start != NULL) { - p_start = _z_cptr_char_offset(p_start, 1); - - const char *p_end = strchr(str, ENDPOINT_CONFIG_SEPARATOR); - if (p_end == NULL) { - p_end = &str[strlen(str)]; - } + // Find metadata separator + const char *p_start = (char *)memchr(_z_string_data(str), LOCATOR_METADATA_SEPARATOR, _z_string_len(str)); + if (p_start == NULL) { + return _Z_RES_OK; + } + p_start = _z_cptr_char_offset(p_start, 1); + size_t start_offset = _z_ptr_char_diff(p_start, _z_string_data(str)); + if (start_offset > _z_string_len(str)) { + return _Z_ERR_CONFIG_LOCATOR_INVALID; + } + if (start_offset == _z_string_len(str)) { + return _Z_RES_OK; + } - if (p_start != p_end) { - size_t p_len = _z_ptr_char_diff(p_end, p_start); - ret = _z_str_intmap_from_strn(strint, p_start, 0, NULL, p_len); - } + const char *p_end = (char *)memchr(_z_string_data(str), ENDPOINT_CONFIG_SEPARATOR, _z_string_len(str)); + if (p_end == NULL) { + p_end = _z_cptr_char_offset(_z_string_data(str), (ptrdiff_t)_z_string_len(str) + 1); } - return ret; + if (p_start != p_end) { + size_t p_len = _z_ptr_char_diff(p_end, p_start); + return _z_str_intmap_from_strn(strint, p_start, 0, NULL, p_len); + } + return _Z_RES_OK; } size_t _z_locator_metadata_strlen(const _z_str_intmap_t *s) { @@ -160,25 +169,17 @@ void _z_locator_metadata_onto_str(char *dst, size_t dst_len, const _z_str_intmap _z_str_intmap_onto_str(dst, dst_len, s, 0, NULL); } -int8_t _z_locator_from_str(_z_locator_t *lc, const char *str) { - int8_t ret = _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; - - // Parse protocol - lc->_protocol = _z_locator_protocol_from_str(str); - if (lc->_protocol != NULL) { - // Parse address - lc->_address = _z_locator_address_from_str(str); - if (lc->_address != NULL) { - // Parse metadata - ret = _z_locator_metadata_from_str(&lc->_metadata, str); - } - } - - if (ret != _Z_RES_OK) { - _z_locator_clear(lc); +int8_t _z_locator_from_string(_z_locator_t *lc, _z_string_t *str) { + if (str == NULL || !_z_string_check(str)) { + return _Z_ERR_CONFIG_LOCATOR_INVALID; } - - return ret; + // Parse protocol + _Z_RETURN_IF_ERR(_z_locator_protocol_from_string(&lc->_protocol, str)); + // Parse address + _Z_CLEAN_RETURN_IF_ERR(_z_locator_address_from_string(&lc->_address, str), _z_locator_clear(lc)); + // Parse metadata + _Z_CLEAN_RETURN_IF_ERR(_z_locator_metadata_from_string(&lc->_metadata, str), _z_locator_clear(lc)); + return _Z_RES_OK; } size_t _z_locator_strlen(const _z_locator_t *l) { @@ -186,9 +187,7 @@ size_t _z_locator_strlen(const _z_locator_t *l) { if (l != NULL) { // Calculate the string length to allocate - ret = ret + strlen(l->_protocol); // Locator protocol - ret = ret + (size_t)1; // Locator protocol separator - ret = ret + strlen(l->_address); // Locator address + ret = _z_string_len(&l->_protocol) + _z_string_len(&l->_address) + 1; // @TODO: define protocol-level metadata size_t md_len = _z_locator_metadata_strlen(&l->_metadata); @@ -207,41 +206,40 @@ size_t _z_locator_strlen(const _z_locator_t *l) { * dst: Pointer to the destination string. It MUST be already allocated with enough space to store the locator in * its string format. loc: :c:type:`_z_locator_t` to be converted into its string format. */ -void __z_locator_onto_str(char *dst, size_t dst_len, const _z_locator_t *loc) { - size_t len = dst_len; +static void __z_locator_onto_string(_z_string_t *dst, const _z_locator_t *loc) { + char *curr_dst = (char *)_z_string_data(dst); const char psep = LOCATOR_PROTOCOL_SEPARATOR; const char msep = LOCATOR_METADATA_SEPARATOR; - dst[0] = '\0'; - len = len - (size_t)1; - - if (len > (size_t)0) { - (void)strncat(dst, loc->_protocol, dst_len); // Locator protocol - len = len - strlen(loc->_protocol); - } - - if (len > (size_t)0) { - (void)strncat(dst, &psep, 1); // Locator protocol separator - len = len - (size_t)1; - } + size_t prot_len = _z_string_len(&loc->_protocol); + size_t addr_len = _z_string_len(&loc->_address); - if (len > (size_t)0) { - (void)strncat(dst, loc->_address, len); // Locator address - len = len - strlen(loc->_address); + if ((prot_len + addr_len + 1) > _z_string_len(dst)) { + _Z_ERROR("Buffer too small to write locator"); + return; } - + // Locator protocol + memcpy(curr_dst, _z_string_data(&loc->_protocol), prot_len); + curr_dst = _z_ptr_char_offset(curr_dst, (ptrdiff_t)prot_len); + // Locator protocol separator + memcpy(curr_dst, &psep, 1); + curr_dst = _z_ptr_char_offset(curr_dst, 1); + // Locator address + memcpy(curr_dst, _z_string_data(&loc->_address), addr_len); + curr_dst = _z_ptr_char_offset(curr_dst, (ptrdiff_t)addr_len); // @TODO: define protocol-level metadata size_t md_len = _z_locator_metadata_strlen(&loc->_metadata); if (md_len > (size_t)0) { - if (len > (size_t)0) { - (void)strncat(dst, &msep, 1); // Locator metadata separator - len = len - (size_t)1; - } - - if (len > (size_t)0) { - _z_locator_metadata_onto_str(&dst[strlen(dst)], len, &loc->_metadata); - len = len - md_len; + size_t curr_len = _z_string_len(dst) - _z_ptr_char_diff(curr_dst, _z_string_data(dst)); + if (curr_len == 0) { + _Z_ERROR("Buffer too small to write metadata"); + return; } + // Locator metadata separator + memcpy(curr_dst, &msep, 1); + curr_dst = _z_ptr_char_offset(curr_dst, 1); + // Locator metadata + _z_locator_metadata_onto_str(curr_dst, curr_len, &loc->_metadata); } } @@ -256,10 +254,10 @@ void __z_locator_onto_str(char *dst, size_t dst_len, const _z_locator_t *loc) { */ _z_string_t _z_locator_to_string(const _z_locator_t *loc) { _z_string_t s = _z_string_preallocate(_z_locator_strlen(loc)); - if (_z_string_is_empty(&s)) { + if (!_z_string_check(&s)) { return s; } - __z_locator_onto_str((char *)_z_string_data(&s), _z_string_len(&s) + 1, loc); + __z_locator_onto_string(&s, loc); return s; } @@ -286,166 +284,167 @@ void _z_endpoint_free(_z_endpoint_t **ep) { } } -int8_t _z_endpoint_config_from_str(_z_str_intmap_t *strint, const char *str, const char *proto) { - int8_t ret = _Z_RES_OK; - - char *p_start = strchr(str, ENDPOINT_CONFIG_SEPARATOR); +int8_t _z_endpoint_config_from_string(_z_str_intmap_t *strint, _z_string_t *str, _z_string_t *proto) { + char *p_start = (char *)memchr(_z_string_data(str), ENDPOINT_CONFIG_SEPARATOR, _z_string_len(str)); if (p_start != NULL) { p_start = _z_ptr_char_offset(p_start, 1); // Call the right configuration parser depending on the protocol + _z_string_t cmp_str = _z_string_null(); #if Z_FEATURE_LINK_TCP == 1 - if (_z_str_eq(proto, TCP_SCHEMA) == true) { - ret = _z_tcp_config_from_str(strint, p_start); - } else + cmp_str = _z_string_from_str(TCP_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_tcp_config_from_str(strint, p_start); + } #endif #if Z_FEATURE_LINK_UDP_UNICAST == 1 || Z_FEATURE_LINK_UDP_MULTICAST == 1 - if (_z_str_eq(proto, UDP_SCHEMA) == true) { - ret = _z_udp_config_from_str(strint, p_start); - } else + cmp_str = _z_string_from_str(UDP_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_udp_config_from_str(strint, p_start); + } #endif #if Z_FEATURE_LINK_BLUETOOTH == 1 - if (_z_str_eq(proto, BT_SCHEMA) == true) { - ret = _z_bt_config_from_str(strint, p_start); - } else + cmp_str = _z_string_from_str(BT_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_bt_config_from_str(strint, p_start); + } #endif #if Z_FEATURE_LINK_SERIAL == 1 - if (_z_str_eq(proto, SERIAL_SCHEMA) == true) { - ret = _z_serial_config_from_str(strint, p_start); - } else + cmp_str = _z_string_from_str(SERIAL_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_serial_config_from_str(strint, p_start); + } #endif #if Z_FEATURE_LINK_WS == 1 - if (_z_str_eq(proto, WS_SCHEMA) == true) { - ret = _z_ws_config_from_str(strint, p_start); - } else + cmp_str = _z_string_from_str(WS_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_ws_config_from_str(strint, p_start); + } #endif - if (_z_str_eq(proto, RAWETH_SCHEMA) == true) { - _z_raweth_config_from_str(strint, p_start); - } else { - ret = _Z_ERR_CONFIG_LOCATOR_SCHEMA_UNKNOWN; + cmp_str = _z_string_from_str(RAWETH_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_raweth_config_from_str(strint, p_start); } } - - return ret; + return _Z_RES_OK; } -size_t _z_endpoint_config_strlen(const _z_str_intmap_t *s, const char *proto) { - size_t len = 0; - +size_t _z_endpoint_config_strlen(const _z_str_intmap_t *s, _z_string_t *proto) { // Call the right configuration parser depending on the protocol + _z_string_t cmp_str = _z_string_null(); #if Z_FEATURE_LINK_TCP == 1 - if (_z_str_eq(proto, TCP_SCHEMA) == true) { - len = _z_tcp_config_strlen(s); - } else + cmp_str = _z_string_from_str(TCP_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_tcp_config_strlen(s); + } #endif #if Z_FEATURE_LINK_UDP_UNICAST == 1 || Z_FEATURE_LINK_UDP_MULTICAST == 1 - if (_z_str_eq(proto, UDP_SCHEMA) == true) { - len = _z_udp_config_strlen(s); - } else + cmp_str = _z_string_from_str(UDP_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_udp_config_strlen(s); + } #endif #if Z_FEATURE_LINK_BLUETOOTH == 1 - if (_z_str_eq(proto, BT_SCHEMA) == true) { - len = _z_bt_config_strlen(s); - } else + cmp_str = _z_string_from_str(BT_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_bt_config_strlen(s); + } #endif #if Z_FEATURE_LINK_SERIAL == 1 - if (_z_str_eq(proto, SERIAL_SCHEMA) == true) { - len = _z_serial_config_strlen(s); - } else + cmp_str = _z_string_from_str(SERIAL_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_serial_config_strlen(s); + } #endif #if Z_FEATURE_LINK_WS == 1 - if (_z_str_eq(proto, WS_SCHEMA) == true) { - len = _z_ws_config_strlen(s); - } else + cmp_str = _z_string_from_str(WS_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_ws_config_strlen(s); + } #endif - if (_z_str_eq(proto, RAWETH_SCHEMA) == true) { - len = _z_raweth_config_strlen(s); + cmp_str = _z_string_from_str(RAWETH_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_raweth_config_strlen(s); } - return len; + return 0; } -char *_z_endpoint_config_to_str(const _z_str_intmap_t *s, const char *proto) { - char *res = NULL; - +char *_z_endpoint_config_to_string(const _z_str_intmap_t *s, const _z_string_t *proto) { // Call the right configuration parser depending on the protocol + _z_string_t cmp_str = _z_string_null(); + #if Z_FEATURE_LINK_TCP == 1 - if (_z_str_eq(proto, TCP_SCHEMA) == true) { - res = _z_tcp_config_to_str(s); - } else + cmp_str = _z_string_from_str(TCP_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_tcp_config_to_str(s); + } #endif #if Z_FEATURE_LINK_UDP_UNICAST == 1 || Z_FEATURE_LINK_UDP_MULTICAST == 1 - if (_z_str_eq(proto, UDP_SCHEMA) == true) { - res = _z_udp_config_to_str(s); - } else + cmp_str = _z_string_from_str(UDP_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_udp_config_to_str(s); + } #endif #if Z_FEATURE_LINK_BLUETOOTH == 1 - if (_z_str_eq(proto, BT_SCHEMA) == true) { - res = _z_bt_config_to_str(s); - } else + cmp_str = _z_string_from_str(BT_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_bt_config_to_str(s); + } #endif #if Z_FEATURE_LINK_SERIAL == 1 - if (_z_str_eq(proto, SERIAL_SCHEMA) == true) { - res = _z_serial_config_to_str(s); - } else + cmp_str = _z_string_from_str(SERIAL_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_serial_config_to_str(s); + } #endif #if Z_FEATURE_LINK_WS == 1 - if (_z_str_eq(proto, WS_SCHEMA) == true) { - res = _z_ws_config_to_str(s); - } else + cmp_str = _z_string_from_str(WS_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_ws_config_to_str(s); + } #endif - if (_z_str_eq(proto, RAWETH_SCHEMA) == true) { - _z_raweth_config_to_str(s); + cmp_str = _z_string_from_str(RAWETH_SCHEMA); + if (_z_string_equals(proto, &cmp_str)) { + return _z_raweth_config_to_str(s); } - return res; + return NULL; } -int8_t _z_endpoint_from_str(_z_endpoint_t *ep, const char *str) { - int8_t ret = _Z_RES_OK; +int8_t _z_endpoint_from_string(_z_endpoint_t *ep, _z_string_t *str) { _z_endpoint_init(ep); - - ret = _z_locator_from_str(&ep->_locator, str); - if (ret == _Z_RES_OK) { - ret = _z_endpoint_config_from_str(&ep->_config, str, ep->_locator._protocol); - } - - if (ret != _Z_RES_OK) { - _z_endpoint_clear(ep); - } - - return ret; + _Z_CLEAN_RETURN_IF_ERR(_z_locator_from_string(&ep->_locator, str), _z_endpoint_clear(ep)); + _Z_CLEAN_RETURN_IF_ERR(_z_endpoint_config_from_string(&ep->_config, str, &ep->_locator._protocol), + _z_endpoint_clear(ep)); + return _Z_RES_OK; } -char *_z_endpoint_to_str(const _z_endpoint_t *endpoint) { - char *ret = NULL; +_z_string_t _z_endpoint_to_string(const _z_endpoint_t *endpoint) { + _z_string_t ret = _z_string_null(); // Retrieve locator _z_string_t locator = _z_locator_to_string(&endpoint->_locator); - if (_z_string_is_empty(&locator)) { - return NULL; + if (!_z_string_check(&locator)) { + return _z_string_null(); } size_t curr_len = _z_string_len(&locator); // Retrieve config - char *config = _z_endpoint_config_to_str(&endpoint->_config, endpoint->_locator._protocol); + char *config = _z_endpoint_config_to_string(&endpoint->_config, &endpoint->_locator._protocol); + size_t config_len = 0; if (config != NULL) { - curr_len += strlen(config) + (size_t)1; // Content + separator; + config_len = strlen(config); + curr_len += config_len; } // Reconstruct the endpoint as a string - ret = (char *)z_malloc(curr_len); - if (ret == NULL) { - return NULL; + ret = _z_string_preallocate(curr_len); + if (!_z_string_check(&ret)) { + return ret; } - ret[0] = '\0'; - curr_len -= (size_t)1; // Copy locator - if (curr_len > (size_t)0) { - (void)strncat(ret, _z_string_data(&locator), curr_len); - curr_len -= _z_string_len(&locator); - } + char *curr_dst = (char *)_z_string_data(&ret); + memcpy(curr_dst, _z_string_data(&locator), _z_string_len(&locator)); + curr_dst = _z_ptr_char_offset(curr_dst, (ptrdiff_t)_z_string_len(&locator)); // Copy config if (config != NULL) { - if (curr_len > (size_t)0) { - (void)strncat(ret, config, curr_len); - curr_len -= strlen(config); - } + memcpy(curr_dst, config, config_len); } // Clean up _z_string_clear(&locator); diff --git a/src/link/link.c b/src/link/link.c index b00a20211..e7a20fba0 100644 --- a/src/link/link.c +++ b/src/link/link.c @@ -21,11 +21,11 @@ #include "zenoh-pico/link/manager.h" #include "zenoh-pico/utils/logging.h" -int8_t _z_open_link(_z_link_t *zl, const char *locator) { +int8_t _z_open_link(_z_link_t *zl, _z_string_t *locator) { int8_t ret = _Z_RES_OK; _z_endpoint_t ep; - ret = _z_endpoint_from_str(&ep, locator); + ret = _z_endpoint_from_string(&ep, locator); if (ret == _Z_RES_OK) { // TODO[peer]: when peer unicast mode is supported, this must be revisited // Create transport link @@ -74,11 +74,11 @@ int8_t _z_open_link(_z_link_t *zl, const char *locator) { return ret; } -int8_t _z_listen_link(_z_link_t *zl, const char *locator) { +int8_t _z_listen_link(_z_link_t *zl, _z_string_t *locator) { int8_t ret = _Z_RES_OK; _z_endpoint_t ep; - ret = _z_endpoint_from_str(&ep, locator); + ret = _z_endpoint_from_string(&ep, locator); if (ret == _Z_RES_OK) { // TODO[peer]: when peer unicast mode is supported, this must be revisited // Create transport link diff --git a/src/link/multicast/udp.c b/src/link/multicast/udp.c index ef1aab5ca..675cc3792 100644 --- a/src/link/multicast/udp.c +++ b/src/link/multicast/udp.c @@ -15,6 +15,7 @@ #include "zenoh-pico/link/config/udp.h" #include +#include #include #include @@ -25,30 +26,37 @@ #if Z_FEATURE_LINK_UDP_MULTICAST == 1 -char *__z_parse_port_segment_udp_multicast(const char *address) { +static char *__z_parse_port_segment_udp_multicast(_z_string_t *address) { char *ret = NULL; - const char *p_start = strrchr(address, ':'); - if (p_start != NULL) { - p_start = _z_cptr_char_offset(p_start, 1); - - const char *p_end = &address[strlen(address)]; + const char *p_start = _z_string_rchr(address, ':'); + if (p_start == NULL) { + return ret; + } + p_start = _z_cptr_char_offset(p_start, 1); + const char *p_end = _z_cptr_char_offset(_z_string_data(address), (ptrdiff_t)_z_string_len(address)); - size_t len = _z_ptr_char_diff(p_end, p_start) + (size_t)1; - ret = (char *)z_malloc(len); - if (ret != NULL) { - _z_str_n_copy(ret, p_start, len); - } + if (p_start >= p_end) { + return ret; + } + size_t len = _z_ptr_char_diff(p_end, p_start) + (size_t)1; + ret = (char *)z_malloc(len); + if (ret != NULL) { + _z_str_n_copy(ret, p_start, len); } return ret; } -char *__z_parse_address_segment_udp_multicast(const char *address) { +static char *__z_parse_address_segment_udp_multicast(_z_string_t *address) { char *ret = NULL; - const char *p_start = &address[0]; - const char *p_end = strrchr(address, ':'); + const char *p_start = _z_string_data(address); + const char *p_end = _z_string_rchr(address, ':'); + + if ((p_start == NULL) || (p_end == NULL)) { + return ret; + } // IPv6 if ((p_start[0] == '[') && (p_end[-1] == ']')) { @@ -63,7 +71,7 @@ char *__z_parse_address_segment_udp_multicast(const char *address) { // IPv4 else { size_t len = _z_ptr_char_diff(p_end, p_start) + (size_t)1; - ret = (char *)z_malloc(len); + ret = (char *)z_malloc(len + 1); if (ret != NULL) { _z_str_n_copy(ret, p_start, len); } @@ -75,12 +83,13 @@ char *__z_parse_address_segment_udp_multicast(const char *address) { int8_t _z_endpoint_udp_multicast_valid(_z_endpoint_t *endpoint) { int8_t ret = _Z_RES_OK; - if (_z_str_eq(endpoint->_locator._protocol, UDP_SCHEMA) != true) { + _z_string_t udp_str = _z_string_from_str(UDP_SCHEMA); + if (!_z_string_equals(&endpoint->_locator._protocol, &udp_str)) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } if (ret == _Z_RES_OK) { - char *s_address = __z_parse_address_segment_udp_multicast(endpoint->_locator._address); + char *s_address = __z_parse_address_segment_udp_multicast(&endpoint->_locator._address); if (s_address == NULL) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } else { @@ -89,7 +98,7 @@ int8_t _z_endpoint_udp_multicast_valid(_z_endpoint_t *endpoint) { } if (ret == _Z_RES_OK) { - char *s_port = __z_parse_port_segment_udp_multicast(endpoint->_locator._address); + char *s_port = __z_parse_port_segment_udp_multicast(&endpoint->_locator._address); if (s_port == NULL) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } else { @@ -179,8 +188,8 @@ int8_t _z_new_link_udp_multicast(_z_link_t *zl, _z_endpoint_t endpoint) { zl->_mtu = _z_get_link_mtu_udp_multicast(); zl->_endpoint = endpoint; - char *s_address = __z_parse_address_segment_udp_multicast(endpoint._locator._address); - char *s_port = __z_parse_port_segment_udp_multicast(endpoint._locator._address); + char *s_address = __z_parse_address_segment_udp_multicast(&endpoint._locator._address); + char *s_port = __z_parse_port_segment_udp_multicast(&endpoint._locator._address); ret = _z_create_endpoint_udp(&zl->_socket._udp._rep, s_address, s_port); memset(&zl->_socket._udp._lep, 0, sizeof(zl->_socket._udp._lep)); z_free(s_address); diff --git a/src/link/unicast/tcp.c b/src/link/unicast/tcp.c index c1b54becf..38254a178 100644 --- a/src/link/unicast/tcp.c +++ b/src/link/unicast/tcp.c @@ -25,31 +25,37 @@ #if Z_FEATURE_LINK_TCP == 1 -char *__z_parse_port_segment_tcp(char *address) { +static char *__z_parse_port_segment_tcp(_z_string_t *address) { char *ret = NULL; - const char *p_start = strrchr(address, ':'); - if (p_start != NULL) { - p_start = _z_cptr_char_offset(p_start, 1); - - const char *p_end = &address[strlen(address)]; + const char *p_start = _z_string_rchr(address, ':'); + if (p_start == NULL) { + return ret; + } + p_start = _z_cptr_char_offset(p_start, 1); + const char *p_end = _z_cptr_char_offset(_z_string_data(address), (ptrdiff_t)_z_string_len(address)); - size_t len = _z_ptr_char_diff(p_end, p_start) + (size_t)1; - ret = (char *)z_malloc(len); - if (ret != NULL) { - _z_str_n_copy(ret, p_start, len); - } + if (p_start >= p_end) { + return ret; + } + size_t len = _z_ptr_char_diff(p_end, p_start) + (size_t)1; + ret = (char *)z_malloc(len); + if (ret != NULL) { + _z_str_n_copy(ret, p_start, len); } return ret; } -char *__z_parse_address_segment_tcp(char *address) { +static char *__z_parse_address_segment_tcp(_z_string_t *address) { char *ret = NULL; - const char *p_start = &address[0]; - const char *p_end = strrchr(address, ':'); + const char *p_start = _z_string_data(address); + const char *p_end = _z_string_rchr(address, ':'); + if ((p_start == NULL) || (p_end == NULL)) { + return ret; + } // IPv6 if ((p_start[0] == '[') && (p_end[-1] == ']')) { p_start = _z_cptr_char_offset(p_start, 1); @@ -75,12 +81,13 @@ char *__z_parse_address_segment_tcp(char *address) { int8_t _z_endpoint_tcp_valid(_z_endpoint_t *endpoint) { int8_t ret = _Z_RES_OK; - if (_z_str_eq(endpoint->_locator._protocol, TCP_SCHEMA) != true) { + _z_string_t tcp_str = _z_string_from_str(TCP_SCHEMA); + if (!_z_string_equals(&endpoint->_locator._protocol, &tcp_str)) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } if (ret == _Z_RES_OK) { - char *s_address = __z_parse_address_segment_tcp(endpoint->_locator._address); + char *s_address = __z_parse_address_segment_tcp(&endpoint->_locator._address); if (s_address == NULL) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } else { @@ -89,7 +96,7 @@ int8_t _z_endpoint_tcp_valid(_z_endpoint_t *endpoint) { } if (ret == _Z_RES_OK) { - char *s_port = __z_parse_port_segment_tcp(endpoint->_locator._address); + char *s_port = __z_parse_port_segment_tcp(&endpoint->_locator._address); if (s_port == NULL) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } else { @@ -163,8 +170,8 @@ int8_t _z_new_link_tcp(_z_link_t *zl, _z_endpoint_t *endpoint) { zl->_mtu = _z_get_link_mtu_tcp(); zl->_endpoint = *endpoint; - char *s_address = __z_parse_address_segment_tcp(endpoint->_locator._address); - char *s_port = __z_parse_port_segment_tcp(endpoint->_locator._address); + char *s_address = __z_parse_address_segment_tcp(&endpoint->_locator._address); + char *s_port = __z_parse_port_segment_tcp(&endpoint->_locator._address); ret = _z_create_endpoint_tcp(&zl->_socket._tcp._rep, s_address, s_port); z_free(s_address); z_free(s_port); diff --git a/src/link/unicast/udp.c b/src/link/unicast/udp.c index d30418727..fbb1520ed 100644 --- a/src/link/unicast/udp.c +++ b/src/link/unicast/udp.c @@ -15,6 +15,7 @@ #include "zenoh-pico/link/config/udp.h" #include +#include #include #include @@ -25,31 +26,37 @@ #if Z_FEATURE_LINK_UDP_UNICAST == 1 -char *__z_parse_port_segment_udp_unicast(char *address) { +static char *__z_parse_port_segment_udp_unicast(_z_string_t *address) { char *ret = NULL; - const char *p_start = strrchr(address, ':'); - if (p_start != NULL) { - p_start = _z_cptr_char_offset(p_start, 1); - - const char *p_end = &address[strlen(address)]; + const char *p_start = _z_string_rchr(address, ':'); + if (p_start == NULL) { + return ret; + } + p_start = _z_cptr_char_offset(p_start, 1); + const char *p_end = _z_cptr_char_offset(_z_string_data(address), (ptrdiff_t)_z_string_len(address)); - size_t len = _z_ptr_char_diff(p_end, p_start) + (size_t)1; - ret = (char *)z_malloc(len); - if (ret != NULL) { - _z_str_n_copy(ret, p_start, len); - } + if (p_start >= p_end) { + return ret; + } + size_t len = _z_ptr_char_diff(p_end, p_start) + (size_t)1; + ret = (char *)z_malloc(len); + if (ret != NULL) { + _z_str_n_copy(ret, p_start, len); } return ret; } -char *__z_parse_address_segment_udp_unicast(char *address) { +static char *__z_parse_address_segment_udp_unicast(_z_string_t *address) { char *ret = NULL; - const char *p_start = &address[0]; - const char *p_end = strrchr(address, ':'); + const char *p_start = _z_string_data(address); + const char *p_end = _z_string_rchr(address, ':'); + if ((p_start == NULL) || (p_end == NULL)) { + return ret; + } // IPv6 if ((p_start[0] == '[') && (p_end[-1] == ']')) { p_start = _z_cptr_char_offset(p_start, 1); @@ -75,12 +82,13 @@ char *__z_parse_address_segment_udp_unicast(char *address) { int8_t _z_endpoint_udp_unicast_valid(_z_endpoint_t *endpoint) { int8_t ret = _Z_RES_OK; - if (_z_str_eq(endpoint->_locator._protocol, UDP_SCHEMA) != true) { + _z_string_t udp_str = _z_string_from_str(UDP_SCHEMA); + if (!_z_string_equals(&endpoint->_locator._protocol, &udp_str)) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } if (ret == _Z_RES_OK) { - char *s_address = __z_parse_address_segment_udp_unicast(endpoint->_locator._address); + char *s_address = __z_parse_address_segment_udp_unicast(&endpoint->_locator._address); if (s_address == NULL) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } else { @@ -89,7 +97,7 @@ int8_t _z_endpoint_udp_unicast_valid(_z_endpoint_t *endpoint) { } if (ret == _Z_RES_OK) { - char *s_port = __z_parse_port_segment_udp_unicast(endpoint->_locator._address); + char *s_port = __z_parse_port_segment_udp_unicast(&endpoint->_locator._address); if (s_port == NULL) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } else { @@ -169,8 +177,8 @@ int8_t _z_new_link_udp_unicast(_z_link_t *zl, _z_endpoint_t endpoint) { zl->_mtu = _z_get_link_mtu_udp_unicast(); zl->_endpoint = endpoint; - char *s_address = __z_parse_address_segment_udp_unicast(endpoint._locator._address); - char *s_port = __z_parse_port_segment_udp_unicast(endpoint._locator._address); + char *s_address = __z_parse_address_segment_udp_unicast(&endpoint._locator._address); + char *s_port = __z_parse_port_segment_udp_unicast(&endpoint._locator._address); ret = _z_create_endpoint_udp(&zl->_socket._udp._rep, s_address, s_port); z_free(s_address); z_free(s_port); diff --git a/src/link/unicast/ws.c b/src/link/unicast/ws.c index fd7590849..630678d7c 100644 --- a/src/link/unicast/ws.c +++ b/src/link/unicast/ws.c @@ -26,14 +26,14 @@ #if Z_FEATURE_LINK_WS == 1 -char *__z_parse_port_segment_ws(char *address) { +char *__z_parse_port_segment_ws(_z_string_t *address) { char *ret = NULL; - const char *p_start = strrchr(address, ':'); + const char *p_start = _z_string_rchr(address, ':'); if (p_start != NULL) { p_start = _z_cptr_char_offset(p_start, 1); - const char *p_end = &address[strlen(address)]; + const char *p_end = _z_cptr_char_offset(_z_string_data(address), (ptrdiff_t)_z_string_len(address)); size_t len = _z_ptr_char_diff(p_end, p_start) + (size_t)1; ret = (char *)z_malloc(len); @@ -45,11 +45,11 @@ char *__z_parse_port_segment_ws(char *address) { return ret; } -char *__z_parse_address_segment_ws(char *address) { +char *__z_parse_address_segment_ws(_z_string_t *address) { char *ret = NULL; - const char *p_start = &address[0]; - const char *p_end = strrchr(address, ':'); + const char *p_start = _z_string_data(address); + const char *p_end = _z_string_rchr(address, ':'); // IPv6 if ((p_start[0] == '[') && (p_end[-1] == ']')) { @@ -76,12 +76,13 @@ char *__z_parse_address_segment_ws(char *address) { int8_t _z_endpoint_ws_valid(_z_endpoint_t *endpoint) { int8_t ret = _Z_RES_OK; - if (_z_str_eq(endpoint->_locator._protocol, WS_SCHEMA) != true) { + _z_string_t str = _z_string_from_str(WS_SCHEMA); + if (_z_string_equals(&endpoint->_locator._protocol, &str)) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } if (ret == _Z_RES_OK) { - char *s_addr = __z_parse_address_segment_ws(endpoint->_locator._address); + char *s_addr = __z_parse_address_segment_ws(&endpoint->_locator._address); if (s_addr == NULL) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } else { @@ -90,7 +91,7 @@ int8_t _z_endpoint_ws_valid(_z_endpoint_t *endpoint) { } if (ret == _Z_RES_OK) { - char *s_port = __z_parse_port_segment_ws(endpoint->_locator._address); + char *s_port = __z_parse_port_segment_ws(&endpoint->_locator._address); if (s_port == NULL) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } else { @@ -164,8 +165,8 @@ int8_t _z_new_link_ws(_z_link_t *zl, _z_endpoint_t *endpoint) { zl->_mtu = _z_get_link_mtu_ws(); zl->_endpoint = *endpoint; - char *s_addr = __z_parse_address_segment_ws(endpoint->_locator._address); - char *s_port = __z_parse_port_segment_ws(endpoint->_locator._address); + char *s_addr = __z_parse_address_segment_ws(&endpoint->_locator._address); + char *s_port = __z_parse_port_segment_ws(&endpoint->_locator._address); ret = _z_create_endpoint_ws(&zl->_socket._ws._rep, s_addr, s_port); z_free(s_addr); z_free(s_port); diff --git a/src/net/primitives.c b/src/net/primitives.c index ec1695332..ff5cb34d5 100644 --- a/src/net/primitives.c +++ b/src/net/primitives.c @@ -37,7 +37,7 @@ #include "zenoh-pico/utils/result.h" /*------------------ Scouting ------------------*/ -void _z_scout(const z_what_t what, const _z_id_t zid, const char *locator, const uint32_t timeout, +void _z_scout(const z_what_t what, const _z_id_t zid, _z_string_t *locator, const uint32_t timeout, _z_hello_handler_t callback, void *arg_call, _z_drop_handler_t dropper, void *arg_drop) { _z_hello_list_t *hellos = _z_scout_inner(what, zid, locator, timeout, false); @@ -324,7 +324,7 @@ int8_t _z_send_reply(const _z_query_t *query, const _z_session_rc_t *zsrc, _z_ke if (query->_anyke == false) { q_ke = _z_get_expanded_key_from_key(zn, &query->_key); r_ke = _z_get_expanded_key_from_key(zn, &keyexpr); - if (_z_keyexpr_intersects(q_ke._suffix, strlen(q_ke._suffix), r_ke._suffix, strlen(r_ke._suffix)) == false) { + if (_z_keyexpr_suffix_intersects(&q_ke, &r_ke) == false) { ret = _Z_ERR_KEYEXPR_NOT_MATCH; } _z_keyexpr_clear(&q_ke); diff --git a/src/net/sample.c b/src/net/sample.c index 9219ba93f..fc1444241 100644 --- a/src/net/sample.c +++ b/src/net/sample.c @@ -35,10 +35,7 @@ _Bool _z_sample_check(const _z_sample_t *sample) { } void _z_sample_move(_z_sample_t *dst, _z_sample_t *src) { - dst->keyexpr._id = src->keyexpr._id; // FIXME: call the z_keyexpr_move - dst->keyexpr._suffix = src->keyexpr._suffix; // FIXME: call the z_keyexpr_move - src->keyexpr._suffix = NULL; // FIXME: call the z_keyexpr_move - + _z_keyexpr_move(&dst->keyexpr, &src->keyexpr); _z_bytes_move(&dst->payload, &src->payload); _z_encoding_move(&dst->encoding, &src->encoding); _z_bytes_move(&dst->attachment, &src->attachment); diff --git a/src/net/session.c b/src/net/session.c index 9ddd7f2d3..8a60bcb41 100644 --- a/src/net/session.c +++ b/src/net/session.c @@ -37,7 +37,7 @@ #include "zenoh-pico/utils/logging.h" #include "zenoh-pico/utils/uuid.h" -int8_t __z_open_inner(_z_session_rc_t *zn, char *locator, z_whatami_t mode) { +int8_t __z_open_inner(_z_session_rc_t *zn, _z_string_t *locator, z_whatami_t mode) { int8_t ret = _Z_RES_OK; _z_id_t local_zid = _z_id_empty(); @@ -79,7 +79,7 @@ int8_t _z_open(_z_session_rc_t *zn, _z_config_t *config) { if (opt_as_str == NULL) { opt_as_str = (char *)Z_CONFIG_MULTICAST_LOCATOR_DEFAULT; } - char *mcast_locator = opt_as_str; + _z_string_t mcast_locator = _z_string_from_str(opt_as_str); opt_as_str = _z_config_get(config, Z_CONFIG_SCOUTING_TIMEOUT_KEY); if (opt_as_str == NULL) { @@ -88,7 +88,7 @@ int8_t _z_open(_z_session_rc_t *zn, _z_config_t *config) { uint32_t timeout = (uint32_t)strtoul(opt_as_str, NULL, 10); // Scout and return upon the first result - _z_hello_list_t *hellos = _z_scout_inner(what, zid, mcast_locator, timeout, true); + _z_hello_list_t *hellos = _z_scout_inner(what, zid, &mcast_locator, timeout, true); if (hellos != NULL) { _z_hello_t *hello = _z_hello_list_head(hellos); _z_string_svec_copy(&locators, &hello->_locators); @@ -132,7 +132,7 @@ int8_t _z_open(_z_session_rc_t *zn, _z_config_t *config) { } if (ret == _Z_RES_OK) { - ret = __z_open_inner(zn, (char *)_z_string_data(locator), mode); + ret = __z_open_inner(zn, locator, mode); if (ret == _Z_RES_OK) { break; } diff --git a/src/protocol/codec/declarations.c b/src/protocol/codec/declarations.c index e5537ab4f..451a1d05c 100644 --- a/src/protocol/codec/declarations.c +++ b/src/protocol/codec/declarations.c @@ -36,20 +36,20 @@ int8_t _z_decl_ext_keyexpr_encode(_z_wbuf_t *wbf, _z_keyexpr_t ke, _Bool has_next_ext) { uint8_t header = _Z_MSG_EXT_ENC_ZBUF | _Z_MSG_EXT_FLAG_M | 0x0f | (has_next_ext ? _Z_FLAG_Z_Z : 0); _Z_RETURN_IF_ERR(_z_uint8_encode(wbf, header)); - uint32_t kelen = (uint32_t)(_z_keyexpr_has_suffix(ke) ? strlen(ke._suffix) : 0); + uint32_t kelen = (uint32_t)(_z_keyexpr_has_suffix(&ke) ? _z_string_len(&ke._suffix) : 0); header = (_z_keyexpr_is_local(&ke) ? 2 : 0) | (kelen != 0 ? 1 : 0); _Z_RETURN_IF_ERR(_z_zsize_encode(wbf, 1 + kelen + _z_zint_len(ke._id))); _Z_RETURN_IF_ERR(_z_uint8_encode(wbf, header)); _Z_RETURN_IF_ERR(_z_zsize_encode(wbf, ke._id)); if (kelen) { - _Z_RETURN_IF_ERR(_z_wbuf_write_bytes(wbf, (const uint8_t *)ke._suffix, 0, kelen)) + _Z_RETURN_IF_ERR(_z_wbuf_write_bytes(wbf, (const uint8_t *)_z_string_data(&ke._suffix), 0, kelen)) } return _Z_RES_OK; } int8_t _z_decl_kexpr_encode(_z_wbuf_t *wbf, const _z_decl_kexpr_t *decl) { uint8_t header = _Z_DECL_KEXPR_MID; - int has_kesuffix = _z_keyexpr_has_suffix(decl->_keyexpr); + int has_kesuffix = _z_keyexpr_has_suffix(&decl->_keyexpr); if (has_kesuffix) { header |= _Z_DECL_KEXPR_FLAG_N; } @@ -61,7 +61,7 @@ int8_t _z_decl_kexpr_encode(_z_wbuf_t *wbf, const _z_decl_kexpr_t *decl) { } int8_t _z_decl_commons_encode(_z_wbuf_t *wbf, uint8_t header, _Bool has_extensions, uint32_t id, _z_keyexpr_t keyexpr) { - _Bool has_kesuffix = _z_keyexpr_has_suffix(keyexpr); + _Bool has_kesuffix = _z_keyexpr_has_suffix(&keyexpr); if (has_extensions) { header |= _Z_FLAG_Z_Z; } @@ -204,15 +204,14 @@ int8_t _z_undecl_decode_extensions(_z_msg_ext_t *extension, void *ctx) { _Z_RETURN_IF_ERR(_z_zint16_decode(&ke->_id, zbf)); if (_Z_HAS_FLAG(header, 1)) { size_t len = _z_zbuf_len(zbf); - ke->_suffix = z_malloc(len + 1); - if (!ke->_suffix) { + ke->_suffix = _z_string_preallocate(len); + if (!_z_keyexpr_has_suffix(ke)) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } - ke->_mapping = _z_keyexpr_mapping(mapping, true); - _z_zbuf_read_bytes(zbf, (uint8_t *)ke->_suffix, 0, len); - ke->_suffix[len] = 0; + ke->_mapping = _z_keyexpr_mapping(mapping); + _z_zbuf_read_bytes(zbf, (uint8_t *)_z_string_data(&ke->_suffix), 0, len); } else { - ke->_mapping = _z_keyexpr_mapping(mapping, false); + ke->_mapping = _z_keyexpr_mapping(mapping); } } break; default: @@ -241,16 +240,15 @@ int8_t _z_decl_commons_decode(_z_zbuf_t *zbf, uint8_t header, _Bool *has_extensi if (_z_zbuf_len(zbf) < len) { return _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; } - ke->_suffix = z_malloc(len + 1); - if (ke->_suffix == NULL) { + ke->_suffix = _z_string_preallocate(len); + if (!_z_keyexpr_has_suffix(ke)) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } - ke->_mapping = _z_keyexpr_mapping(mapping, true); - _z_zbuf_read_bytes(zbf, (uint8_t *)ke->_suffix, 0, len); - ke->_suffix[len] = 0; + ke->_mapping = _z_keyexpr_mapping(mapping); + _z_zbuf_read_bytes(zbf, (uint8_t *)_z_string_data(&ke->_suffix), 0, len); } else { - ke->_suffix = NULL; - ke->_mapping = _z_keyexpr_mapping(mapping, false); + ke->_suffix = _z_string_null(); + ke->_mapping = _z_keyexpr_mapping(mapping); } return _Z_RES_OK; } diff --git a/src/protocol/codec/interest.c b/src/protocol/codec/interest.c index 7c6f31bb4..5ead72645 100644 --- a/src/protocol/codec/interest.c +++ b/src/protocol/codec/interest.c @@ -52,7 +52,7 @@ int8_t _z_interest_encode(_z_wbuf_t *wbf, const _z_interest_t *interest, _Bool i // Process restricted flag if (_Z_HAS_FLAG(flags, _Z_INTEREST_FLAG_RESTRICTED)) { // Set Named & Mapping flags - _Bool has_kesuffix = _z_keyexpr_has_suffix(interest->_keyexpr); + _Bool has_kesuffix = _z_keyexpr_has_suffix(&interest->_keyexpr); if (has_kesuffix) { _Z_SET_FLAG(flags, _Z_INTEREST_CODEC_FLAG_N); } diff --git a/src/protocol/codec/message.c b/src/protocol/codec/message.c index 93418575d..cee9e8c27 100644 --- a/src/protocol/codec/message.c +++ b/src/protocol/codec/message.c @@ -115,7 +115,7 @@ int8_t _z_keyexpr_encode(_z_wbuf_t *wbf, _Bool has_suffix, const _z_keyexpr_t *f _Z_RETURN_IF_ERR(_z_zsize_encode(wbf, fld->_id)) if (has_suffix == true) { - _Z_RETURN_IF_ERR(_z_str_encode(wbf, fld->_suffix)) + _Z_RETURN_IF_ERR(_z_string_encode(wbf, &fld->_suffix)) } return ret; @@ -127,17 +127,17 @@ int8_t _z_keyexpr_decode(_z_keyexpr_t *ke, _z_zbuf_t *zbf, _Bool has_suffix) { ret |= _z_zint16_decode(&ke->_id, zbf); if (has_suffix == true) { - char *str = NULL; - ret |= _z_str_decode(&str, zbf); + _z_string_t str = _z_string_null(); + ret |= _z_string_decode(&str, zbf); if (ret == _Z_RES_OK) { ke->_suffix = str; - ke->_mapping = _z_keyexpr_mapping(0, true); + ke->_mapping = _z_keyexpr_mapping(0); } else { - ke->_suffix = NULL; - ke->_mapping = _z_keyexpr_mapping(0, false); + ke->_suffix = _z_string_null(); + ke->_mapping = _z_keyexpr_mapping(0); } } else { - ke->_suffix = NULL; + ke->_suffix = _z_string_null(); } return ret; @@ -168,12 +168,12 @@ int8_t _z_locators_decode_na(_z_locator_array_t *a_loc, _z_zbuf_t *zbf) { // Decode the elements for (size_t i = 0; i < len; i++) { - char *str = NULL; - ret |= _z_str_decode(&str, zbf); + _z_string_t str = _z_string_null(); + ret |= _z_string_decode(&str, zbf); if (ret == _Z_RES_OK) { _z_locator_init(&a_loc->_val[i]); - ret |= _z_locator_from_str(&a_loc->_val[i], str); - z_free(str); + ret |= _z_locator_from_string(&a_loc->_val[i], &str); + _z_string_clear(&str); } else { a_loc->_len = i; } diff --git a/src/protocol/codec/network.c b/src/protocol/codec/network.c index 68bf5d225..e4bcf977c 100644 --- a/src/protocol/codec/network.c +++ b/src/protocol/codec/network.c @@ -40,7 +40,7 @@ int8_t _z_push_encode(_z_wbuf_t *wbf, const _z_n_msg_push_t *msg) { uint8_t header = _Z_MID_N_PUSH | (_z_keyexpr_is_local(&msg->_key) ? _Z_FLAG_N_REQUEST_M : 0); - _Bool has_suffix = _z_keyexpr_has_suffix(msg->_key); + _Bool has_suffix = _z_keyexpr_has_suffix(&msg->_key); _Bool has_qos_ext = msg->_qos._val != _Z_N_QOS_DEFAULT._val; _Bool has_timestamp_ext = _z_timestamp_check(&msg->_timestamp); if (has_suffix) { @@ -114,7 +114,7 @@ int8_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header) { int8_t _z_request_encode(_z_wbuf_t *wbf, const _z_n_msg_request_t *msg) { int8_t ret = _Z_RES_OK; uint8_t header = _Z_MID_N_REQUEST | (_z_keyexpr_is_local(&msg->_key) ? _Z_FLAG_N_REQUEST_M : 0); - _Bool has_suffix = _z_keyexpr_has_suffix(msg->_key); + _Bool has_suffix = _z_keyexpr_has_suffix(&msg->_key); if (has_suffix) { header |= _Z_FLAG_N_REQUEST_N; } @@ -247,7 +247,7 @@ int8_t _z_response_encode(_z_wbuf_t *wbf, const _z_n_msg_response_t *msg) { _Bool has_ts_ext = _z_timestamp_check(&msg->_ext_timestamp); _Bool has_responder_ext = _z_id_check(msg->_ext_responder._zid) || msg->_ext_responder._eid != 0; int n_ext = (has_qos_ext ? 1 : 0) + (has_ts_ext ? 1 : 0) + (has_responder_ext ? 1 : 0); - _Bool has_suffix = _z_keyexpr_has_suffix(msg->_key); + _Bool has_suffix = _z_keyexpr_has_suffix(&msg->_key); if (_z_keyexpr_is_local(&msg->_key)) { _Z_SET_FLAG(header, _Z_FLAG_N_RESPONSE_M); } @@ -262,7 +262,7 @@ int8_t _z_response_encode(_z_wbuf_t *wbf, const _z_n_msg_response_t *msg) { _Z_RETURN_IF_ERR(_z_zsize_encode(wbf, msg->_request_id)); _Z_RETURN_IF_ERR(_z_zsize_encode(wbf, msg->_key._id)); if (has_suffix) { - _Z_RETURN_IF_ERR(_z_str_encode(wbf, msg->_key._suffix)) + _Z_RETURN_IF_ERR(_z_string_encode(wbf, &msg->_key._suffix)) } if (has_qos_ext) { n_ext -= 1; diff --git a/src/protocol/keyexpr.c b/src/protocol/keyexpr.c index f8a7881a1..2a255a0d9 100644 --- a/src/protocol/keyexpr.c +++ b/src/protocol/keyexpr.c @@ -27,20 +27,27 @@ _z_keyexpr_t _z_rname(const char *rname) { return _z_rid_with_suffix(0, rname); _z_keyexpr_t _z_rid_with_suffix(uint16_t rid, const char *suffix) { return (_z_keyexpr_t){ ._id = rid, - ._mapping = _z_keyexpr_mapping(_Z_KEYEXPR_MAPPING_LOCAL, false), - ._suffix = (char *)suffix, + ._mapping = _z_keyexpr_mapping(_Z_KEYEXPR_MAPPING_LOCAL), + ._suffix = (suffix == NULL) ? _z_string_null() : _z_string_from_str(suffix), + }; +} + +_z_keyexpr_t _z_keyexpr_from_string(uint16_t rid, _z_string_t *str) { + return (_z_keyexpr_t){ + ._id = rid, + ._mapping = _z_keyexpr_mapping(_Z_KEYEXPR_MAPPING_LOCAL), + ._suffix = (_z_string_check(str)) ? _z_string_alias(str) : _z_string_null(), }; } int8_t _z_keyexpr_copy(_z_keyexpr_t *dst, const _z_keyexpr_t *src) { *dst = _z_keyexpr_null(); - dst->_suffix = src->_suffix ? _z_str_clone(src->_suffix) : NULL; - if (dst->_suffix == NULL && src->_suffix != NULL) { - return _Z_ERR_SYSTEM_OUT_OF_MEMORY; - } dst->_id = src->_id; dst->_mapping = src->_mapping; - _z_keyexpr_set_owns_suffix(dst, true); + + if (_z_keyexpr_has_suffix(src)) { + _Z_RETURN_IF_ERR(_z_string_copy(&dst->_suffix, &src->_suffix)); + } return _Z_RES_OK; } @@ -50,23 +57,24 @@ _z_keyexpr_t _z_keyexpr_duplicate(_z_keyexpr_t src) { return dst; } -_z_keyexpr_t _z_keyexpr_to_owned(_z_keyexpr_t src) { - return _z_keyexpr_owns_suffix(&src) ? src : _z_keyexpr_duplicate(src); -} - _z_keyexpr_t _z_keyexpr_steal(_Z_MOVE(_z_keyexpr_t) src) { _z_keyexpr_t stolen = *src; *src = _z_keyexpr_null(); return stolen; } +void _z_keyexpr_move(_z_keyexpr_t *dst, _z_keyexpr_t *src) { + dst->_id = src->_id; + dst->_mapping = src->_mapping; + _z_string_move(&dst->_suffix, &src->_suffix); +} + void _z_keyexpr_clear(_z_keyexpr_t *rk) { rk->_id = 0; - if (rk->_suffix != NULL && _z_keyexpr_owns_suffix(rk)) { - _z_str_clear((char *)rk->_suffix); - _z_keyexpr_set_owns_suffix(rk, false); + if (_z_keyexpr_has_suffix(rk)) { + _z_string_clear(&rk->_suffix); } - rk->_suffix = NULL; + rk->_suffix = _z_string_null(); } void _z_keyexpr_free(_z_keyexpr_t **rk) { @@ -79,25 +87,35 @@ void _z_keyexpr_free(_z_keyexpr_t **rk) { *rk = NULL; } } + +_Bool _z_keyexpr_equals(const _z_keyexpr_t *left, const _z_keyexpr_t *right) { + if (left->_id != right->_id) { + return false; + } + if (_z_keyexpr_mapping_id(left) != _z_keyexpr_mapping_id(right)) { + return false; + } + return _z_string_equals(&left->_suffix, &right->_suffix); +} + _z_keyexpr_t _z_keyexpr_alias(_z_keyexpr_t src) { _z_keyexpr_t alias = { ._id = src._id, ._mapping = src._mapping, - ._suffix = src._suffix, + ._suffix = _z_string_alias(&src._suffix), }; - _z_keyexpr_set_owns_suffix(&alias, false); return alias; } _z_keyexpr_t _z_keyexpr_alias_from_user_defined(_z_keyexpr_t src, _Bool try_declared) { - if ((try_declared && src._id != Z_RESOURCE_ID_NONE) || src._suffix == NULL) { + if ((try_declared && src._id != Z_RESOURCE_ID_NONE) || !_z_keyexpr_has_suffix(&src)) { return (_z_keyexpr_t){ ._id = src._id, ._mapping = src._mapping, - ._suffix = NULL, + ._suffix = _z_string_null(), }; } else { - return _z_rname(src._suffix); + return _z_keyexpr_from_string(0, &src._suffix); } } @@ -378,14 +396,14 @@ _Bool _z_keyexpr_has_verbatim(_z_str_se_t s) { return false; } -_Bool _z_keyexpr_includes_superwild(_z_str_se_t left, _z_str_se_t right, _z_ke_chunk_matcher chunk_includer) { +_Bool _z_keyexpr_suffix_includes_superwild(_z_str_se_t left, _z_str_se_t right, _z_ke_chunk_matcher chunk_includer) { for (;;) { _z_str_se_t lchunk = {0}; _z_str_se_t lrest = _z_splitstr_split_once((_z_splitstr_t){.s = left, .delimiter = _Z_DELIMITER}, &lchunk); _Bool lempty = lrest.start == NULL; if (_z_keyexpr_is_superwild_chunk(lchunk)) { if (lempty ? !_z_keyexpr_has_verbatim(right) - : _z_keyexpr_includes_superwild(lrest, right, chunk_includer)) { + : _z_keyexpr_suffix_includes_superwild(lrest, right, chunk_includer)) { return true; } if (right.start[0] == _Z_VERBATIM) { @@ -411,8 +429,13 @@ _Bool _z_keyexpr_includes_superwild(_z_str_se_t left, _z_str_se_t right, _z_ke_c } /*------------------ Zenoh-Core helpers ------------------*/ -_Bool _z_keyexpr_includes(const char *lstart, const size_t llen, const char *rstart, const size_t rlen) { +_Bool _z_keyexpr_suffix_includes(const _z_keyexpr_t *left, const _z_keyexpr_t *right) { + size_t llen = _z_string_len(&left->_suffix); + size_t rlen = _z_string_len(&right->_suffix); + const char *lstart = _z_string_data(&left->_suffix); + const char *rstart = _z_string_data(&right->_suffix); _Bool result = ((llen == rlen) && (strncmp(lstart, rstart, llen) == 0)); + if (result == false) { _z_str_se_t l = {.start = lstart, .end = _z_cptr_char_offset(lstart, (ptrdiff_t)llen)}; _z_str_se_t r = {.start = rstart, .end = _z_cptr_char_offset(rstart, (ptrdiff_t)rlen)}; @@ -426,7 +449,7 @@ _Bool _z_keyexpr_includes(const char *lstart, const size_t llen, const char *rst ? _z_ke_chunk_includes_stardsl : _z_ke_chunk_includes_nodsl; if ((lwildness & (int8_t)_ZP_WILDNESS_SUPERCHUNKS) == (int8_t)_ZP_WILDNESS_SUPERCHUNKS) { - return _z_keyexpr_includes_superwild(l, r, chunk_includer); + return _z_keyexpr_suffix_includes_superwild(l, r, chunk_includer); } else if (((rwildness & (int8_t)_ZP_WILDNESS_SUPERCHUNKS) == 0) && (ln_chunks == rn_chunks)) { _z_splitstr_t lchunks = {.s = l, .delimiter = _Z_DELIMITER}; _z_splitstr_t rchunks = {.s = r, .delimiter = _Z_DELIMITER}; @@ -645,8 +668,13 @@ _Bool _z_keyexpr_intersect_bothsuper(_z_str_se_t l, _z_str_se_t r, _z_ke_chunk_m (_z_splitstr_is_empty(&it2) || _z_keyexpr_is_superwild_chunk(it2.s)); } -_Bool _z_keyexpr_intersects(const char *lstart, const size_t llen, const char *rstart, const size_t rlen) { +_Bool _z_keyexpr_suffix_intersects(const _z_keyexpr_t *left, const _z_keyexpr_t *right) { + size_t llen = _z_string_len(&left->_suffix); + size_t rlen = _z_string_len(&right->_suffix); + const char *lstart = _z_string_data(&left->_suffix); + const char *rstart = _z_string_data(&right->_suffix); _Bool result = ((llen == rlen) && (strncmp(lstart, rstart, llen) == 0)); + if (result == false) { _z_str_se_t l = {.start = lstart, .end = _z_cptr_char_offset(lstart, (ptrdiff_t)llen)}; _z_str_se_t r = {.start = rstart, .end = _z_cptr_char_offset(rstart, (ptrdiff_t)rlen)}; @@ -818,3 +846,19 @@ zp_keyexpr_canon_status_t _z_keyexpr_canonize(char *start, size_t *len) { } zp_keyexpr_canon_status_t _z_keyexpr_is_canon(const char *start, size_t len) { return __zp_canon_prefix(start, &len); } + +_Bool _z_keyexpr_suffix_equals(const _z_keyexpr_t *left, const _z_keyexpr_t *right) { + size_t llen = _z_string_len(&left->_suffix); + size_t rlen = _z_string_len(&right->_suffix); + const char *lstart = _z_string_data(&left->_suffix); + const char *rstart = _z_string_data(&right->_suffix); + + if (lstart != NULL && rstart != NULL) { + if (llen == rlen) { + if (strncmp(lstart, rstart, llen) == 0) { + return true; + } + } + } + return false; +} diff --git a/src/session/interest.c b/src/session/interest.c index dc2bd087e..ef11c7d1f 100644 --- a/src/session/interest.c +++ b/src/session/interest.c @@ -57,14 +57,13 @@ static _z_session_interest_rc_t *__z_get_interest_by_id(_z_session_interest_rc_l } static _z_session_interest_rc_list_t *__z_get_interest_by_key_and_flags(_z_session_interest_rc_list_t *intrs, - uint8_t flags, const _z_keyexpr_t key) { + uint8_t flags, const _z_keyexpr_t *key) { _z_session_interest_rc_list_t *ret = NULL; _z_session_interest_rc_list_t *xs = intrs; while (xs != NULL) { _z_session_interest_rc_t *intr = _z_session_interest_rc_list_head(xs); if ((_Z_RC_IN_VAL(intr)->_flags & flags) != 0) { - if (_z_keyexpr_intersects(_Z_RC_IN_VAL(intr)->_key._suffix, strlen(_Z_RC_IN_VAL(intr)->_key._suffix), - key._suffix, strlen(key._suffix))) { + if (_z_keyexpr_suffix_intersects(&_Z_RC_IN_VAL(intr)->_key, key)) { ret = _z_session_interest_rc_list_push(ret, _z_session_interest_rc_clone_as_ptr(intr)); } } @@ -89,7 +88,7 @@ static _z_session_interest_rc_t *__unsafe_z_get_interest_by_id(_z_session_t *zn, * - zn->_mutex_inner */ static _z_session_interest_rc_list_t *__unsafe_z_get_interest_by_key_and_flags(_z_session_t *zn, uint8_t flags, - const _z_keyexpr_t key) { + const _z_keyexpr_t *key) { _z_session_interest_rc_list_t *intrs = zn->_local_interests; return __z_get_interest_by_key_and_flags(intrs, flags, key); } @@ -193,7 +192,8 @@ _z_session_interest_rc_t *_z_get_interest_by_id(_z_session_t *zn, const _z_zint_ } _z_session_interest_rc_t *_z_register_interest(_z_session_t *zn, _z_session_interest_t *intr) { - _Z_DEBUG(">>> Allocating interest for (%ju:%s)", (uintmax_t)intr->_key._id, intr->_key._suffix); + _Z_DEBUG(">>> Allocating interest for (%ju:%.*s)", (uintmax_t)intr->_key._id, + (int)_z_string_len(&intr->_key._suffix), _z_string_data(&intr->_key._suffix)); _z_session_interest_rc_t *ret = NULL; _zp_session_lock_mutex(zn); @@ -272,14 +272,14 @@ int8_t _z_interest_process_declares(_z_session_t *zn, const _z_declaration_t *de // Retrieve key _zp_session_lock_mutex(zn); _z_keyexpr_t key = __unsafe_z_get_expanded_key_from_key(zn, decl_key); - if (key._suffix == NULL) { + if (!_z_keyexpr_has_suffix(&key)) { _zp_session_unlock_mutex(zn); return _Z_ERR_KEYEXPR_UNKNOWN; } // Register declare _unsafe_z_register_declare(zn, &key, msg.id, decl_type); // Retrieve interests - _z_session_interest_rc_list_t *intrs = __unsafe_z_get_interest_by_key_and_flags(zn, flags, key); + _z_session_interest_rc_list_t *intrs = __unsafe_z_get_interest_by_key_and_flags(zn, flags, &key); _zp_session_unlock_mutex(zn); // Parse session_interest list _z_session_interest_rc_list_t *xs = intrs; @@ -319,11 +319,11 @@ int8_t _z_interest_process_undeclares(_z_session_t *zn, const _z_declaration_t * _zp_session_lock_mutex(zn); // Retrieve declare data _z_keyexpr_t key = _unsafe_z_get_key_from_declare(zn, msg.id, decl_type); - if (key._suffix == NULL) { + if (!_z_keyexpr_has_suffix(&key)) { _zp_session_unlock_mutex(zn); return _Z_ERR_KEYEXPR_UNKNOWN; } - _z_session_interest_rc_list_t *intrs = __unsafe_z_get_interest_by_key_and_flags(zn, flags, key); + _z_session_interest_rc_list_t *intrs = __unsafe_z_get_interest_by_key_and_flags(zn, flags, &key); // Remove declare _unsafe_z_unregister_declare(zn, msg.id, decl_type); _zp_session_unlock_mutex(zn); diff --git a/src/session/query.c b/src/session/query.c index 35fa32175..fef9dbaa0 100644 --- a/src/session/query.c +++ b/src/session/query.c @@ -77,7 +77,8 @@ _z_pending_query_t *_z_get_pending_query_by_id(_z_session_t *zn, const _z_zint_t int8_t _z_register_pending_query(_z_session_t *zn, _z_pending_query_t *pen_qry) { int8_t ret = _Z_RES_OK; - _Z_DEBUG(">>> Allocating query for (%ju:%s)", (uintmax_t)pen_qry->_key._id, pen_qry->_key._suffix); + _Z_DEBUG(">>> Allocating query for (%ju:%.*s)", (uintmax_t)pen_qry->_key._id, + (int)_z_string_len(&pen_qry->_key._suffix), _z_string_data(&pen_qry->_key._suffix)); _zp_session_lock_mutex(zn); @@ -106,8 +107,7 @@ int8_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, cons _z_keyexpr_t expanded_ke = __unsafe_z_get_expanded_key_from_key(zn, &keyexpr); if ((ret == _Z_RES_OK) && - ((pen_qry->_anykey == false) && (_z_keyexpr_intersects(pen_qry->_key._suffix, strlen(pen_qry->_key._suffix), - keyexpr._suffix, strlen(keyexpr._suffix)) == false))) { + ((pen_qry->_anykey == false) && (_z_keyexpr_suffix_intersects(&pen_qry->_key, &keyexpr) == false))) { ret = _Z_ERR_QUERY_NOT_MATCH; } @@ -125,8 +125,8 @@ int8_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, cons pen_rep = _z_pending_reply_list_head(pen_rps); // Check if this is the same resource key - if (_z_str_eq(pen_rep->_reply.data._result.sample.keyexpr._suffix, - reply.data._result.sample.keyexpr._suffix) == true) { + if (_z_string_equals(&pen_rep->_reply.data._result.sample.keyexpr._suffix, + &reply.data._result.sample.keyexpr._suffix) == true) { if (msg->_commons._timestamp.time <= pen_rep->_tstamp.time) { drop = true; } else { diff --git a/src/session/queryable.c b/src/session/queryable.c index c15ec62fc..1e14b69ca 100644 --- a/src/session/queryable.c +++ b/src/session/queryable.c @@ -63,8 +63,7 @@ _z_session_queryable_rc_list_t *__z_get_session_queryable_by_key(_z_session_quer _z_session_queryable_rc_list_t *xs = qles; while (xs != NULL) { _z_session_queryable_rc_t *qle = _z_session_queryable_rc_list_head(xs); - if (_z_keyexpr_intersects(_Z_RC_IN_VAL(qle)->_key._suffix, strlen(_Z_RC_IN_VAL(qle)->_key._suffix), key._suffix, - strlen(key._suffix)) == true) { + if (_z_keyexpr_suffix_intersects(&_Z_RC_IN_VAL(qle)->_key, &key) == true) { ret = _z_session_queryable_rc_list_push(ret, _z_session_queryable_rc_clone_as_ptr(qle)); } @@ -116,7 +115,8 @@ _z_session_queryable_rc_list_t *_z_get_session_queryable_by_key(_z_session_t *zn } _z_session_queryable_rc_t *_z_register_session_queryable(_z_session_t *zn, _z_session_queryable_t *q) { - _Z_DEBUG(">>> Allocating queryable for (%ju:%s)", (uintmax_t)q->_key._id, q->_key._suffix); + _Z_DEBUG(">>> Allocating queryable for (%ju:%.*s)", (uintmax_t)q->_key._id, (int)_z_string_len(&q->_key._suffix), + _z_string_data(&q->_key._suffix)); _z_session_queryable_rc_t *ret = NULL; _zp_session_lock_mutex(zn); @@ -140,7 +140,7 @@ int8_t _z_trigger_queryables(_z_session_rc_t *zsrc, _z_msg_query_t *msgq, const _zp_session_lock_mutex(zn); _z_keyexpr_t key = __unsafe_z_get_expanded_key_from_key(zn, &q_key); - if (key._suffix != NULL) { + if (_z_keyexpr_has_suffix(&key)) { _z_session_queryable_rc_list_t *qles = __unsafe_z_get_session_queryable_by_key(zn, key); _zp_session_unlock_mutex(zn); diff --git a/src/session/resource.c b/src/session/resource.c index ca1305d41..3c165266e 100644 --- a/src/session/resource.c +++ b/src/session/resource.c @@ -25,6 +25,7 @@ #include "zenoh-pico/session/utils.h" #include "zenoh-pico/system/platform.h" #include "zenoh-pico/utils/logging.h" +#include "zenoh-pico/utils/pointers.h" _Bool _z_resource_eq(const _z_resource_t *other, const _z_resource_t *this_) { return this_->_id == other->_id; } @@ -72,13 +73,10 @@ _z_resource_t *__z_get_resource_by_id(_z_resource_list_t *rl, uint16_t mapping, _z_resource_t *__z_get_resource_by_key(_z_resource_list_t *rl, const _z_keyexpr_t *keyexpr) { _z_resource_t *ret = NULL; - uint16_t mapping = _z_keyexpr_mapping_id(keyexpr); - _z_resource_list_t *xs = rl; while (xs != NULL) { _z_resource_t *r = _z_resource_list_head(xs); - if ((r->_key._id == keyexpr->_id) && _z_keyexpr_mapping_id(&r->_key) == mapping && - (_z_str_eq(r->_key._suffix, keyexpr->_suffix) == true)) { + if (_z_keyexpr_equals(&r->_key, keyexpr)) { ret = r; break; } @@ -90,19 +88,19 @@ _z_resource_t *__z_get_resource_by_key(_z_resource_list_t *rl, const _z_keyexpr_ } _z_keyexpr_t __z_get_expanded_key_from_key(_z_resource_list_t *xs, const _z_keyexpr_t *keyexpr) { - _z_keyexpr_t ret = {._id = Z_RESOURCE_ID_NONE, ._suffix = NULL, ._mapping = _z_keyexpr_mapping(0, true)}; + _z_keyexpr_t ret = {._id = Z_RESOURCE_ID_NONE, ._suffix = _z_string_null(), ._mapping = _z_keyexpr_mapping(0)}; // Need to build the complete resource name, by recursively look at RIDs // Resource names are looked up from right to left - _z_str_list_t *strs = NULL; - size_t len = 1; // Start with space for the null-terminator + _z_string_list_t *strs = NULL; + size_t len = 0; // Append suffix as the right-most segment - if (keyexpr->_suffix != NULL) { - len = len + strlen(keyexpr->_suffix); - strs = _z_str_list_push(strs, (char *)keyexpr->_suffix); // Warning: list must be release with - // _z_list_free(&strs, _z_noop_free); - // or will release the suffix as well + if (_z_keyexpr_has_suffix(keyexpr)) { + len = len + _z_string_len(&keyexpr->_suffix); + strs = _z_string_list_push(strs, (_z_string_t *)&keyexpr->_suffix); // Warning: list must be release with + // _z_list_free(&strs, _z_noop_free); + // or will release the suffix as well } // Recursively go through all the RIDs @@ -114,39 +112,31 @@ _z_keyexpr_t __z_get_expanded_key_from_key(_z_resource_list_t *xs, const _z_keye len = 0; break; } - - if (res->_key._suffix != NULL) { - len = len + strlen(res->_key._suffix); - strs = _z_str_list_push(strs, (char *)res->_key._suffix); // Warning: list must be release with - // _z_list_free(&strs, _z_noop_free); - // or will release the suffix as well + if (_z_keyexpr_has_suffix(&res->_key)) { + len = len + _z_string_len(&res->_key._suffix); + strs = _z_string_list_push(strs, &res->_key._suffix); // Warning: list must be release with + // _z_list_free(&strs, _z_noop_free); + // or will release the suffix as well } id = res->_key._id; } - + // Copy the data if (len != (size_t)0) { - char *rname = NULL; - rname = (char *)z_malloc(len); - if (rname != NULL) { - rname[0] = '\0'; // NULL terminator must be set (required to strcat) - len = len - (size_t)1; + ret._suffix = _z_string_preallocate(len); + if (_z_keyexpr_has_suffix(&ret)) { + char *curr_ptr = (char *)_z_string_data(&ret._suffix); // Concatenate all the partial resource names - _z_str_list_t *xstr = strs; + _z_string_list_t *xstr = strs; while (xstr != NULL) { - char *s = _z_str_list_head(xstr); - if (len > (size_t)0) { - (void)strncat(rname, s, len); - len = len - strlen(s); - } - xstr = _z_str_list_tail(xstr); + _z_string_t *s = _z_string_list_head(xstr); + memcpy(curr_ptr, _z_string_data(s), _z_string_len(s)); + curr_ptr = _z_ptr_char_offset(curr_ptr, (ptrdiff_t)_z_string_len(s)); + xstr = _z_string_list_tail(xstr); } - ret._suffix = rname; } } - _z_list_free(&strs, _z_noop_free); - return ret; } @@ -191,7 +181,7 @@ _z_resource_t *_z_get_resource_by_id(_z_session_t *zn, uint16_t mapping, _z_zint } _z_resource_t *_z_get_resource_by_key(_z_session_t *zn, const _z_keyexpr_t *keyexpr) { - if (keyexpr->_suffix == NULL) { + if (!_z_keyexpr_has_suffix(keyexpr)) { return _z_get_resource_by_id(zn, _z_keyexpr_mapping_id(keyexpr), keyexpr->_id); } _zp_session_lock_mutex(zn); @@ -230,13 +220,13 @@ uint16_t _z_register_resource(_z_session_t *zn, _z_keyexpr_t key, uint16_t id, u } } ret = key._id; - if ((key._suffix != NULL)) { + if (_z_keyexpr_has_suffix(&key)) { _z_resource_t *res = z_malloc(sizeof(_z_resource_t)); if (res == NULL) { ret = Z_RESOURCE_ID_NONE; } else { res->_refcount = 1; - res->_key = _z_keyexpr_to_owned(key); + res->_key = _z_keyexpr_duplicate(key); ret = id == Z_RESOURCE_ID_NONE ? _z_get_resource_id(zn) : id; res->_id = ret; // Register the resource diff --git a/src/session/scout.c b/src/session/scout.c index 2bfc3951a..0430e4f07 100644 --- a/src/session/scout.c +++ b/src/session/scout.c @@ -25,16 +25,17 @@ #error "Scouting UDP requires UDP unicast links to be enabled (Z_FEATURE_LINK_UDP_UNICAST = 1 in config.h)" #endif -_z_hello_list_t *__z_scout_loop(const _z_wbuf_t *wbf, const char *locator, unsigned long period, _Bool exit_on_first) { +_z_hello_list_t *__z_scout_loop(const _z_wbuf_t *wbf, _z_string_t *locator, unsigned long period, _Bool exit_on_first) { // Define an empty array _z_hello_list_t *ret = NULL; int8_t err = _Z_RES_OK; _z_endpoint_t ep; - err = _z_endpoint_from_str(&ep, locator); + err = _z_endpoint_from_string(&ep, locator); #if Z_FEATURE_SCOUTING_UDP == 1 - if ((err == _Z_RES_OK) && (_z_str_eq(ep._locator._protocol, UDP_SCHEMA) == true)) { + _z_string_t cmp_str = _z_string_from_str(UDP_SCHEMA); + if ((err == _Z_RES_OK) && _z_string_equals(&ep._locator._protocol, &cmp_str)) { _z_endpoint_clear(&ep); } else #endif @@ -128,7 +129,7 @@ _z_hello_list_t *__z_scout_loop(const _z_wbuf_t *wbf, const char *locator, unsig return ret; } -_z_hello_list_t *_z_scout_inner(const z_what_t what, _z_id_t zid, const char *locator, const uint32_t timeout, +_z_hello_list_t *_z_scout_inner(const z_what_t what, _z_id_t zid, _z_string_t *locator, const uint32_t timeout, const _Bool exit_on_first) { _z_hello_list_t *ret = NULL; diff --git a/src/session/subscription.c b/src/session/subscription.c index 0d739816f..90a681ff2 100644 --- a/src/session/subscription.c +++ b/src/session/subscription.c @@ -57,14 +57,13 @@ _z_subscription_rc_t *__z_get_subscription_by_id(_z_subscription_rc_list_t *subs return ret; } -_z_subscription_rc_list_t *__z_get_subscriptions_by_key(_z_subscription_rc_list_t *subs, const _z_keyexpr_t key) { +_z_subscription_rc_list_t *__z_get_subscriptions_by_key(_z_subscription_rc_list_t *subs, const _z_keyexpr_t *key) { _z_subscription_rc_list_t *ret = NULL; _z_subscription_rc_list_t *xs = subs; while (xs != NULL) { _z_subscription_rc_t *sub = _z_subscription_rc_list_head(xs); - if (_z_keyexpr_intersects(_Z_RC_IN_VAL(sub)->_key._suffix, strlen(_Z_RC_IN_VAL(sub)->_key._suffix), key._suffix, - strlen(key._suffix)) == true) { + if (_z_keyexpr_suffix_intersects(&_Z_RC_IN_VAL(sub)->_key, key) == true) { ret = _z_subscription_rc_list_push(ret, _z_subscription_rc_clone_as_ptr(sub)); } @@ -91,7 +90,7 @@ _z_subscription_rc_t *__unsafe_z_get_subscription_by_id(_z_session_t *zn, uint8_ * - zn->_mutex_inner */ _z_subscription_rc_list_t *__unsafe_z_get_subscriptions_by_key(_z_session_t *zn, uint8_t is_local, - const _z_keyexpr_t key) { + const _z_keyexpr_t *key) { _z_subscription_rc_list_t *subs = (is_local == _Z_RESOURCE_IS_LOCAL) ? zn->_local_subscriptions : zn->_remote_subscriptions; return __z_get_subscriptions_by_key(subs, key); @@ -110,7 +109,7 @@ _z_subscription_rc_t *_z_get_subscription_by_id(_z_session_t *zn, uint8_t is_loc _z_subscription_rc_list_t *_z_get_subscriptions_by_key(_z_session_t *zn, uint8_t is_local, const _z_keyexpr_t *key) { _zp_session_lock_mutex(zn); - _z_subscription_rc_list_t *subs = __unsafe_z_get_subscriptions_by_key(zn, is_local, *key); + _z_subscription_rc_list_t *subs = __unsafe_z_get_subscriptions_by_key(zn, is_local, key); _zp_session_unlock_mutex(zn); @@ -118,7 +117,8 @@ _z_subscription_rc_list_t *_z_get_subscriptions_by_key(_z_session_t *zn, uint8_t } _z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_t *s) { - _Z_DEBUG(">>> Allocating sub decl for (%ju:%s)", (uintmax_t)s->_key._id, s->_key._suffix); + _Z_DEBUG(">>> Allocating sub decl for (%ju:%.*s)", (uintmax_t)s->_key._id, (int)_z_string_len(&s->_key._suffix), + _z_string_data(&s->_key._suffix)); _z_subscription_rc_t *ret = NULL; _zp_session_lock_mutex(zn); @@ -153,11 +153,12 @@ int8_t _z_trigger_subscriptions(_z_session_t *zn, const _z_keyexpr_t keyexpr, co _zp_session_lock_mutex(zn); - _Z_DEBUG("Resolving %d - %s on mapping 0x%x", keyexpr._id, keyexpr._suffix, _z_keyexpr_mapping_id(&keyexpr)); + _Z_DEBUG("Resolving %d - %.*s on mapping 0x%x", keyexpr._id, (int)_z_string_len(&keyexpr._suffix), + _z_string_data(&keyexpr._suffix), _z_keyexpr_mapping_id(&keyexpr)); _z_keyexpr_t key = __unsafe_z_get_expanded_key_from_key(zn, &keyexpr); - _Z_DEBUG("Triggering subs for %d - %s", key._id, key._suffix); - if (key._suffix != NULL) { - _z_subscription_rc_list_t *subs = __unsafe_z_get_subscriptions_by_key(zn, _Z_RESOURCE_IS_LOCAL, key); + _Z_DEBUG("Triggering subs for %d - %.*s", key._id, (int)_z_string_len(&key._suffix), _z_string_data(&key._suffix)); + if (_z_keyexpr_has_suffix(&key)) { + _z_subscription_rc_list_t *subs = __unsafe_z_get_subscriptions_by_key(zn, _Z_RESOURCE_IS_LOCAL, &key); _zp_session_unlock_mutex(zn); diff --git a/src/transport/manager.c b/src/transport/manager.c index 3d430465f..5d9f1646c 100644 --- a/src/transport/manager.c +++ b/src/transport/manager.c @@ -20,7 +20,7 @@ #include "zenoh-pico/transport/multicast/transport.h" #include "zenoh-pico/transport/unicast/transport.h" -int8_t _z_new_transport_client(_z_transport_t *zt, char *locator, _z_id_t *local_zid) { +int8_t _z_new_transport_client(_z_transport_t *zt, _z_string_t *locator, _z_id_t *local_zid) { int8_t ret = _Z_RES_OK; // Init link _z_link_t zl; @@ -62,7 +62,7 @@ int8_t _z_new_transport_client(_z_transport_t *zt, char *locator, _z_id_t *local return ret; } -int8_t _z_new_transport_peer(_z_transport_t *zt, char *locator, _z_id_t *local_zid) { +int8_t _z_new_transport_peer(_z_transport_t *zt, _z_string_t *locator, _z_id_t *local_zid) { int8_t ret = _Z_RES_OK; // Init link _z_link_t zl; @@ -101,7 +101,7 @@ int8_t _z_new_transport_peer(_z_transport_t *zt, char *locator, _z_id_t *local_z return ret; } -int8_t _z_new_transport(_z_transport_t *zt, _z_id_t *bs, char *locator, z_whatami_t mode) { +int8_t _z_new_transport(_z_transport_t *zt, _z_id_t *bs, _z_string_t *locator, z_whatami_t mode) { int8_t ret; if (mode == Z_WHATAMI_CLIENT) { diff --git a/src/transport/raweth/link.c b/src/transport/raweth/link.c index a8c45492a..056f44178 100644 --- a/src/transport/raweth/link.c +++ b/src/transport/raweth/link.c @@ -63,7 +63,7 @@ const uint16_t _ZP_RAWETH_DEFAULT_ETHTYPE = 0x72e0; const char *_ZP_RAWETH_DEFAULT_INTERFACE = "lo"; const uint8_t _ZP_RAWETH_DEFAULT_SMAC[_ZP_MAC_ADDR_LENGTH] = {0x30, 0x03, 0xc8, 0x37, 0x25, 0xa1}; const _zp_raweth_mapping_entry_t _ZP_RAWETH_DEFAULT_MAPPING = { - {0, {0}, ""}, 0x0000, {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, false}; + {0, {0}, {{0, NULL, {NULL, NULL}}}}, 0x0000, {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, false}; static _Bool _z_valid_iface_raweth(_z_str_intmap_t *config); static const char *_z_get_iface_raweth(_z_str_intmap_t *config); @@ -75,6 +75,7 @@ static size_t _z_valid_whitelist_raweth(_z_str_intmap_t *config); static int8_t _z_get_whitelist_raweth(_z_str_intmap_t *config, _zp_raweth_whitelist_array_t *array, size_t size); static int8_t _z_get_mapping_entry(char *entry, _zp_raweth_mapping_entry_t *storage); static _Bool _z_valid_mapping_entry(char *entry); +static _Bool _z_valid_address_raweth_inner(const _z_string_t *address); static _Bool _z_valid_address_raweth(const char *address); static uint8_t *_z_parse_address_raweth(const char *address); static int8_t _z_f_link_open_raweth(_z_link_t *self); @@ -310,22 +311,23 @@ static _Bool _z_valid_mapping_entry(char *entry) { return true; } -static _Bool _z_valid_address_raweth(const char *address) { +static _Bool _z_valid_address_raweth_inner(const _z_string_t *address) { // Check if the string has the correct length - size_t len = strlen(address); + size_t len = _z_string_len(address); + const char *str_data = _z_string_data(address); if (len != 17) { // 6 pairs of hexadecimal digits and 5 colons return false; } // Check if the colons are at the correct positions for (size_t i = 2; i < len; i += 3) { - if (address[i] != ':') { + if (str_data[i] != ':') { return false; } } // Check if each character is a valid hexadecimal digit for (size_t i = 0; i < len; ++i) { if (i % 3 != 2) { - char c = address[i]; + char c = str_data[i]; if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) { return false; } @@ -334,6 +336,11 @@ static _Bool _z_valid_address_raweth(const char *address) { return true; } +static _Bool _z_valid_address_raweth(const char *address) { + _z_string_t addr_str = _z_string_from_str(address); + return _z_valid_address_raweth_inner(&addr_str); +} + static uint8_t *_z_parse_address_raweth(const char *address) { // Allocate data uint8_t *ret = (uint8_t *)z_malloc(_ZP_MAC_ADDR_LENGTH); @@ -356,8 +363,8 @@ static int8_t _z_f_link_open_raweth(_z_link_t *self) { self->_socket._raweth._mapping = _zp_raweth_mapping_array_empty(); self->_socket._raweth._whitelist = _zp_raweth_whitelist_array_empty(); // Init socket smac - if (_z_valid_address_raweth(self->_endpoint._locator._address)) { - uint8_t *addr = _z_parse_address_raweth(self->_endpoint._locator._address); + if (_z_valid_address_raweth_inner(&self->_endpoint._locator._address)) { + uint8_t *addr = _z_parse_address_raweth(_z_string_data(&self->_endpoint._locator._address)); memcpy(&self->_socket._raweth._smac, addr, _ZP_MAC_ADDR_LENGTH); z_free(addr); } else { @@ -452,7 +459,8 @@ int8_t _z_endpoint_raweth_valid(_z_endpoint_t *endpoint) { int8_t ret = _Z_RES_OK; // Check the root - if (!_z_str_eq(endpoint->_locator._protocol, RAWETH_SCHEMA)) { + _z_string_t str_cmp = _z_string_from_str(RAWETH_SCHEMA); + if (!_z_string_equals(&endpoint->_locator._protocol, &str_cmp)) { ret = _Z_ERR_CONFIG_LOCATOR_INVALID; } return ret; diff --git a/src/transport/raweth/tx.c b/src/transport/raweth/tx.c index 9393d20bc..7e21ff6a6 100644 --- a/src/transport/raweth/tx.c +++ b/src/transport/raweth/tx.c @@ -40,7 +40,7 @@ static int _zp_raweth_find_map_entry(const _z_keyexpr_t *keyexpr, _z_raweth_sock for (size_t i = 0; i < _zp_raweth_mapping_array_len(&sock->_mapping); i++) { // Find matching keyexpr const _zp_raweth_mapping_entry_t *entry = _zp_raweth_mapping_array_get(&sock->_mapping, i); - if (zp_keyexpr_intersect_null_terminated(keyexpr->_suffix, entry->_keyexpr._suffix) != _Z_RES_OK) { + if (z_keyexpr_intersects(keyexpr, &entry->_keyexpr) != _Z_RES_OK) { continue; } return (int)i; @@ -69,7 +69,8 @@ static int8_t _zp_raweth_set_socket(const _z_keyexpr_t *keyexpr, _z_raweth_socke // Key not found case if (idx < 0) { idx = 0; // Set to default entry - _Z_DEBUG("Key '%s' wasn't found in config mapping, sending to default address", keyexpr->_suffix); + _Z_DEBUG("Key '%.*s' wasn't found in config mapping, sending to default address", + (int)_z_string_len(&keyexpr->_suffix), _z_string_data(&keyexpr->_suffix)); } // Store data into socket const _zp_raweth_mapping_entry_t *entry = _zp_raweth_mapping_array_get(&sock->_mapping, (size_t)idx); diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index e98de29da..c90a27238 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -141,23 +141,10 @@ int main(int argc, char **argv) { _Bool _ret_bool = z_keyexpr_includes(z_loan(key_demo_example_starstar), z_loan(key_demo_example_a)); assert(_ret_bool); -#ifdef ZENOH_PICO - _ret_bool = zp_keyexpr_includes_null_terminated("demo/example/**", "demo/example/a"); - assert(_ret_bool); -#endif _ret_bool = z_keyexpr_intersects(z_loan(key_demo_example_starstar), z_loan(key_demo_example_a)); assert(_ret_bool); -#ifdef ZENOH_PICO - _ret_bool = zp_keyexpr_intersect_null_terminated("demo/example/**", "demo/example/a"); - assert(_ret_bool); -#endif _ret_bool = z_keyexpr_equals(z_loan(key_demo_example_starstar), z_loan(key_demo_example)); assert(!_ret_bool); -#ifdef ZENOH_PICO - _ret_bool = zp_keyexpr_equals_null_terminated("demo/example/**", "demo/example"); - assert(!_ret_bool); -#endif - z_sleep_s(SLEEP); size_t keyexpr_len = strlen(URI); @@ -167,18 +154,9 @@ int main(int argc, char **argv) { int8_t _ret_int8 = z_keyexpr_is_canon(keyexpr_str, keyexpr_len); assert(_ret_int8 < 0); -#ifdef ZENOH_PICO - _ret_int8 = zp_keyexpr_is_canon_null_terminated(keyexpr_str); - assert(_ret_int8 < 0); -#endif _ret_int8 = z_keyexpr_canonize(keyexpr_str, &keyexpr_len); assert_eq(_ret_int8, 0); assert_eq(strlen(URI), keyexpr_len); -#ifdef ZENOH_PICO - _ret_int8 = zp_keyexpr_canonize_null_terminated(keyexpr_str); - assert_eq(_ret_int8, 0); - assert_eq(strlen(URI), keyexpr_len); -#endif printf("Ok\n"); z_sleep_s(SLEEP); diff --git a/tests/z_client_test.c b/tests/z_client_test.c index ba8afdb3d..a8a03cc0a 100644 --- a/tests/z_client_test.c +++ b/tests/z_client_test.c @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, +#include #include #include #include @@ -99,13 +100,14 @@ void data_handler(const z_loaned_sample_t *sample, void *arg) { snprintf(res, 64, "%s%u", uri, *(unsigned int *)arg); printf(">> Received data: %s\t(%u/%u)\n", res, datas, total); + _z_string_t res_str = _z_string_from_str(res); 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); size_t payload_len = z_slice_len(z_loan(value)); assert((payload_len == MSG_LEN) || (payload_len == FRAGMENT_MSG_LEN)); - assert(_z_str_eq(z_string_data(z_loan(k_str)), res) == true); + assert(_z_string_equals(z_loan(k_str), &res_str)); datas++; z_drop(z_move(value)); @@ -167,7 +169,8 @@ int main(int argc, char **argv) { z_view_keyexpr_from_str(&ke, s1_res); z_owned_keyexpr_t expr; z_declare_keyexpr(&expr, z_loan(s1), z_loan(ke)); - printf("Declared resource on session 1: %u %s\n", z_loan(expr)->_id, z_loan(expr)->_suffix); + printf("Declared resource on session 1: %u %.*s\n", z_loan(expr)->_id, + (int)z_string_len(&z_loan(expr)->_suffix), z_string_data(&z_loan(expr)->_suffix)); rids1[i] = expr; } @@ -179,7 +182,8 @@ int main(int argc, char **argv) { z_view_keyexpr_from_str(&ke, s1_res); z_owned_keyexpr_t expr; z_declare_keyexpr(&expr, z_loan(s2), z_loan(ke)); - printf("Declared resource on session 2: %u %s\n", z_loan(expr)->_id, z_loan(expr)->_suffix); + printf("Declared resource on session 2: %u %.*s\n", z_loan(expr)->_id, + (int)z_string_len(&z_loan(expr)->_suffix), z_string_data(&z_loan(expr)->_suffix)); rids2[i] = expr; } diff --git a/tests/z_endpoint_test.c b/tests/z_endpoint_test.c index 621955c9d..41ecd677f 100644 --- a/tests/z_endpoint_test.c +++ b/tests/z_endpoint_test.c @@ -25,116 +25,88 @@ #include int main(void) { - char *s = (char *)malloc(64); - // Locator printf(">>> Testing locators...\n"); - int8_t ret = _Z_RES_OK; _z_locator_t lc; - snprintf(s, 64, "tcp/127.0.0.1:7447"); - printf("- %s\n", s); - ret = _z_locator_from_str(&lc, s); - assert(ret == _Z_RES_OK); - assert(_z_str_eq(lc._protocol, "tcp") == true); - assert(_z_str_eq(lc._address, "127.0.0.1:7447") == true); + _z_string_t str = _z_string_from_str("tcp/127.0.0.1:7447"); + assert(_z_locator_from_string(&lc, &str) == _Z_RES_OK); + + str = _z_string_from_str("tcp"); + assert(_z_string_equals(&lc._protocol, &str) == true); + str = _z_string_from_str("127.0.0.1:7447"); + assert(_z_string_equals(&lc._address, &str) == true); assert(_z_str_intmap_is_empty(&lc._metadata) == true); _z_locator_clear(&lc); - s[0] = '\0'; // snprintf(s, ""); - printf("- %s\n", s); - ret = _z_locator_from_str(&lc, s); - assert(ret == _Z_ERR_MESSAGE_DESERIALIZATION_FAILED); + str = _z_string_from_str(""); + assert(_z_locator_from_string(&lc, &str) == _Z_ERR_CONFIG_LOCATOR_INVALID); - snprintf(s, 64, "/"); - printf("- %s\n", s); - ret = _z_locator_from_str(&lc, "/"); - assert(ret == _Z_ERR_MESSAGE_DESERIALIZATION_FAILED); + str = _z_string_from_str("/"); + assert(_z_locator_from_string(&lc, &str) == _Z_ERR_CONFIG_LOCATOR_INVALID); - snprintf(s, 64, "tcp"); - printf("- %s\n", s); - ret = _z_locator_from_str(&lc, s); - assert(ret == _Z_ERR_MESSAGE_DESERIALIZATION_FAILED); + str = _z_string_from_str("tcp"); + assert(_z_locator_from_string(&lc, &str) == _Z_ERR_CONFIG_LOCATOR_INVALID); - snprintf(s, 64, "tcp/"); - printf("- %s\n", s); - ret = _z_locator_from_str(&lc, s); - assert(ret == _Z_ERR_MESSAGE_DESERIALIZATION_FAILED); + str = _z_string_from_str("tcp/"); + assert(_z_locator_from_string(&lc, &str) == _Z_ERR_CONFIG_LOCATOR_INVALID); - snprintf(s, 64, "127.0.0.1:7447"); - printf("- %s\n", s); - ret = _z_locator_from_str(&lc, s); - assert(ret == _Z_ERR_MESSAGE_DESERIALIZATION_FAILED); + str = _z_string_from_str("127.0.0.1:7447"); + assert(_z_locator_from_string(&lc, &str) == _Z_ERR_CONFIG_LOCATOR_INVALID); - snprintf(s, 64, "tcp/127.0.0.1:7447?"); - printf("- %s\n", s); - ret = _z_locator_from_str(&lc, s); - assert(ret == _Z_RES_OK); + str = _z_string_from_str("tcp/127.0.0.1:7447?"); + assert(_z_locator_from_string(&lc, &str) == _Z_RES_OK); // No metadata defined so far... but this is a valid syntax in principle - snprintf(s, 64, "tcp/127.0.0.1:7447?invalid=ctrl"); - printf("- %s\n", s); - ret = _z_locator_from_str(&lc, s); - assert(ret == _Z_RES_OK); + str = _z_string_from_str("tcp/127.0.0.1:7447?invalid=ctrl"); + assert(_z_locator_from_string(&lc, &str) == _Z_RES_OK); // Endpoint printf(">>> Testing endpoints...\n"); _z_endpoint_t ep; - snprintf(s, 64, "tcp/127.0.0.1:7447"); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_RES_OK); - assert(_z_str_eq(ep._locator._protocol, "tcp") == true); - assert(_z_str_eq(ep._locator._address, "127.0.0.1:7447") == true); + str = _z_string_from_str("tcp/127.0.0.1:7447"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_RES_OK); + + str = _z_string_from_str("tcp"); + assert(_z_string_equals(&ep._locator._protocol, &str) == true); + str = _z_string_from_str("127.0.0.1:7447"); + assert(_z_string_equals(&ep._locator._address, &str) == true); assert(_z_str_intmap_is_empty(&ep._locator._metadata) == true); assert(_z_str_intmap_is_empty(&ep._config) == true); _z_endpoint_clear(&ep); - s[0] = '\0'; // snprintf(s, ""); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_ERR_MESSAGE_DESERIALIZATION_FAILED); + str = _z_string_from_str(""); + assert(_z_endpoint_from_string(&ep, &str) == _Z_ERR_CONFIG_LOCATOR_INVALID); - snprintf(s, 64, "/"); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_ERR_MESSAGE_DESERIALIZATION_FAILED); + str = _z_string_from_str("/"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_ERR_CONFIG_LOCATOR_INVALID); - snprintf(s, 64, "tcp"); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_ERR_MESSAGE_DESERIALIZATION_FAILED); + str = _z_string_from_str("tcp"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_ERR_CONFIG_LOCATOR_INVALID); - snprintf(s, 64, "tcp"); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_ERR_MESSAGE_DESERIALIZATION_FAILED); + str = _z_string_from_str("tcp/"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_ERR_CONFIG_LOCATOR_INVALID); - snprintf(s, 64, "127.0.0.1:7447"); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_ERR_MESSAGE_DESERIALIZATION_FAILED); + str = _z_string_from_str("127.0.0.1:7447"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_ERR_CONFIG_LOCATOR_INVALID); - snprintf(s, 64, "tcp/127.0.0.1:7447?"); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_RES_OK); + str = _z_string_from_str("tcp/127.0.0.1:7447?"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_RES_OK); // No metadata defined so far... but this is a valid syntax in principle - snprintf(s, 64, "tcp/127.0.0.1:7447?invalid=ctrl"); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_RES_OK); - - snprintf(s, 64, "udp/127.0.0.1:7447#%s=eth0", UDP_CONFIG_IFACE_STR); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_RES_OK); - assert(_z_str_eq(ep._locator._protocol, "udp") == true); - assert(_z_str_eq(ep._locator._address, "127.0.0.1:7447") == true); + str = _z_string_from_str("tcp/127.0.0.1:7447?invalid=ctrl"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_RES_OK); + + str = _z_string_from_str("udp/127.0.0.1:7447#iface=eth0"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_RES_OK); + + str = _z_string_from_str("udp"); + assert(_z_string_equals(&ep._locator._protocol, &str) == true); + str = _z_string_from_str("127.0.0.1:7447"); + assert(_z_string_equals(&ep._locator._address, &str) == true); assert(_z_str_intmap_is_empty(&ep._locator._metadata) == true); assert(_z_str_intmap_len(&ep._config) == 1); char *p = _z_str_intmap_get(&ep._config, UDP_CONFIG_IFACE_KEY); @@ -142,20 +114,14 @@ int main(void) { (void)(p); _z_endpoint_clear(&ep); - snprintf(s, 64, "udp/127.0.0.1:7447#invalid=eth0"); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_RES_OK); + str = _z_string_from_str("udp/127.0.0.1:7447#invalid=eth0"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_RES_OK); - snprintf(s, 64, "udp/127.0.0.1:7447?invalid=ctrl#%s=eth0", UDP_CONFIG_IFACE_STR); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_RES_OK); + str = _z_string_from_str("udp/127.0.0.1:7447?invalid=ctrl#iface=eth0"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_RES_OK); - snprintf(s, 64, "udp/127.0.0.1:7447?invalid=ctrl#invalid=eth0"); - printf("- %s\n", s); - ret = _z_endpoint_from_str(&ep, s); - assert(ret == _Z_RES_OK); + str = _z_string_from_str("udp/127.0.0.1:7447?invalid=ctrl#invalid=eth0"); + assert(_z_endpoint_from_string(&ep, &str) == _Z_RES_OK); return 0; } diff --git a/tests/z_keyexpr_test.c b/tests/z_keyexpr_test.c index 3c3c34ce2..764f69941 100644 --- a/tests/z_keyexpr_test.c +++ b/tests/z_keyexpr_test.c @@ -20,270 +20,184 @@ #undef NDEBUG #include +#define TEST_TRUE_INTERSECT(a, b) \ + ke_a = _z_rname(a); \ + ke_b = _z_rname(b); \ + assert(_z_keyexpr_suffix_intersects(&ke_a, &ke_b)); + +#define TEST_FALSE_INTERSECT(a, b) \ + ke_a = _z_rname(a); \ + ke_b = _z_rname(b); \ + assert(!_z_keyexpr_suffix_intersects(&ke_a, &ke_b)); + +#define TEST_TRUE_INCLUDE(a, b) \ + ke_a = _z_rname(a); \ + ke_b = _z_rname(b); \ + assert(_z_keyexpr_suffix_includes(&ke_a, &ke_b)); + +#define TEST_FALSE_INCLUDE(a, b) \ + ke_a = _z_rname(a); \ + ke_b = _z_rname(b); \ + assert(!_z_keyexpr_suffix_includes(&ke_a, &ke_b)); + +#define TEST_TRUE_EQUAL(a, b) \ + ke_a = _z_rname(a); \ + ke_b = _z_rname(b); \ + assert(_z_keyexpr_suffix_equals(&ke_a, &ke_b)); + +#define TEST_FALSE_EQUAL(a, b) \ + ke_a = _z_rname(a); \ + ke_b = _z_rname(b); \ + assert(!_z_keyexpr_suffix_equals(&ke_a, &ke_b)); + void test_intersects(void) { - assert(_z_keyexpr_intersects("a", strlen("a"), "a", strlen("a"))); - assert(_z_keyexpr_intersects("a/b", strlen("a/b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_intersects("*", strlen("*"), "abc", strlen("abc"))); - assert(_z_keyexpr_intersects("*", strlen("*"), "abc", strlen("abc"))); - assert(_z_keyexpr_intersects("*", strlen("*"), "abc", strlen("abc"))); - assert(_z_keyexpr_intersects("*", strlen("*"), "xxx", strlen("xxx"))); - assert(_z_keyexpr_intersects("ab$*", strlen("ab$*"), "abcd", strlen("abcd"))); - assert(_z_keyexpr_intersects("ab$*d", strlen("ab$*d"), "abcd", strlen("abcd"))); - assert(!_z_keyexpr_intersects("ab$*d", strlen("ab$*d"), "abcde", strlen("abcde"))); - assert(_z_keyexpr_intersects("ab$*", strlen("ab$*"), "ab", strlen("ab"))); - assert(!_z_keyexpr_intersects("ab/*", strlen("ab/*"), "ab", strlen("ab"))); - assert(_z_keyexpr_intersects("a/*/c/*/e", strlen("a/*/c/*/e"), "a/b/c/d/e", strlen("a/b/c/d/e"))); - assert(_z_keyexpr_intersects("a/**/d/**/l", strlen("a/**/d/**/l"), "a/b/c/d/e/f/g/h/i/l", - strlen("a/b/c/d/e/f/g/h/i/l"))); - assert(_z_keyexpr_intersects("a/**/d/**/l", strlen("a/**/d/**/l"), "a/d/foo/l", strlen("a/d/foo/l"))); - assert(_z_keyexpr_intersects("a/$*b/c/$*d/e", strlen("a/$*b/c/$*d/e"), "a/xb/c/xd/e", strlen("a/xb/c/xd/e"))); - assert(!_z_keyexpr_intersects("a/*/c/*/e", strlen("a/*/c/*/e"), "a/c/e", strlen("a/c/e"))); - assert(!_z_keyexpr_intersects("a/*/c/*/e", strlen("a/*/c/*/e"), "a/b/c/d/x/e", strlen("a/b/c/d/x/e"))); - assert(!_z_keyexpr_intersects("ab$*cd", strlen("ab$*cd"), "abxxcxxd", strlen("abxxcxxd"))); - assert(_z_keyexpr_intersects("ab$*cd", strlen("ab$*cd"), "abxxcxxcd", strlen("abxxcxxcd"))); - assert(!_z_keyexpr_intersects("ab$*cd", strlen("ab$*cd"), "abxxcxxcdx", strlen("abxxcxxcdx"))); - assert(_z_keyexpr_intersects("**", strlen("**"), "abc", strlen("abc"))); - assert(_z_keyexpr_intersects("**", strlen("**"), "a/b/c", strlen("a/b/c"))); - assert(_z_keyexpr_intersects("ab/**", strlen("ab/**"), "ab", strlen("ab"))); - assert(_z_keyexpr_intersects("**/xyz", strlen("**/xyz"), "a/b/xyz/d/e/f/xyz", strlen("a/b/xyz/d/e/f/xyz"))); - assert( - !_z_keyexpr_intersects("**/xyz$*xyz", strlen("**/xyz$*xyz"), "a/b/xyz/d/e/f/xyz", strlen("a/b/xyz/d/e/f/xyz"))); - assert( - _z_keyexpr_intersects("a/**/c/**/e", strlen("a/**/c/**/e"), "a/b/b/b/c/d/d/d/e", strlen("a/b/b/b/c/d/d/d/e"))); - assert(_z_keyexpr_intersects("a/**/c/**/e", strlen("a/**/c/**/e"), "a/c/e", strlen("a/c/e"))); - assert(_z_keyexpr_intersects("a/**/c/*/e/*", strlen("a/**/c/*/e/*"), "a/b/b/b/c/d/d/c/d/e/f", - strlen("a/b/b/b/c/d/d/c/d/e/f"))); - assert(!_z_keyexpr_intersects("a/**/c/*/e/*", strlen("a/**/c/*/e/*"), "a/b/b/b/c/d/d/c/d/d/e/f", - strlen("a/b/b/b/c/d/d/c/d/d/e/f"))); - assert(!_z_keyexpr_intersects("ab$*cd", strlen("ab$*cd"), "abxxcxxcdx", strlen("abxxcxxcdx"))); - assert(_z_keyexpr_intersects("x/abc", strlen("x/abc"), "x/abc", strlen("x/abc"))); - assert(!_z_keyexpr_intersects("x/abc", strlen("x/abc"), "abc", strlen("abc"))); - assert(_z_keyexpr_intersects("x/*", strlen("x/*"), "x/abc", strlen("x/abc"))); - assert(!_z_keyexpr_intersects("x/*", strlen("x/*"), "abc", strlen("abc"))); - assert(!_z_keyexpr_intersects("*", strlen("*"), "x/abc", strlen("x/abc"))); - assert(_z_keyexpr_intersects("x/*", strlen("x/*"), "x/abc$*", strlen("x/abc$*"))); - assert(_z_keyexpr_intersects("x/$*abc", strlen("x/$*abc"), "x/abc$*", strlen("x/abc$*"))); - assert(_z_keyexpr_intersects("x/a$*", strlen("x/a$*"), "x/abc$*", strlen("x/abc$*"))); - assert(_z_keyexpr_intersects("x/a$*de", strlen("x/a$*de"), "x/abc$*de", strlen("x/abc$*de"))); - assert(_z_keyexpr_intersects("x/a$*d$*e", strlen("x/a$*d$*e"), "x/a$*e", strlen("x/a$*e"))); - assert(_z_keyexpr_intersects("x/a$*d$*e", strlen("x/a$*d$*e"), "x/a$*c$*e", strlen("x/a$*c$*e"))); - assert(_z_keyexpr_intersects("x/a$*d$*e", strlen("x/a$*d$*e"), "x/ade", strlen("x/ade"))); - assert(!_z_keyexpr_intersects("x/c$*", strlen("x/c$*"), "x/abc$*", strlen("x/abc$*"))); - assert(!_z_keyexpr_intersects("x/$*d", strlen("x/$*d"), "x/$*e", strlen("x/$*e"))); - assert(_z_keyexpr_intersects("a", strlen("a"), "a", strlen("a"))); - assert(_z_keyexpr_intersects("a/b", strlen("a/b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_intersects("*", strlen("*"), "a", strlen("a"))); - assert(_z_keyexpr_intersects("a", strlen("a"), "*", strlen("*"))); - assert(_z_keyexpr_intersects("*", strlen("*"), "aaaaa", strlen("aaaaa"))); - assert(_z_keyexpr_intersects("**", strlen("**"), "a", strlen("a"))); - assert(_z_keyexpr_intersects("a", strlen("a"), "**", strlen("**"))); - assert(_z_keyexpr_intersects("**", strlen("**"), "a", strlen("a"))); - assert(_z_keyexpr_intersects("a/a/a/a", strlen("a/a/a/a"), "**", strlen("**"))); - assert(_z_keyexpr_intersects("a/*", strlen("a/*"), "a/b", strlen("a/b"))); - assert(!_z_keyexpr_intersects("a/*/b", strlen("a/*/b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_intersects("a/**/b", strlen("a/**/b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_intersects("a/b$*", strlen("a/b$*"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_intersects("a/$*b$*", strlen("a/$*b$*"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_intersects("a/$*b", strlen("a/$*b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_intersects("a/b$*", strlen("a/b$*"), "a/bc", strlen("a/bc"))); - assert(_z_keyexpr_intersects("a/$*b$*", strlen("a/$*b$*"), "a/ebc", strlen("a/ebc"))); - assert(_z_keyexpr_intersects("a/$*b", strlen("a/$*b"), "a/cb", strlen("a/cb"))); - assert(!_z_keyexpr_intersects("a/b$*", strlen("a/b$*"), "a/ebc", strlen("a/ebc"))); - assert(!_z_keyexpr_intersects("a/$*b", strlen("a/$*b"), "a/cbc", strlen("a/cbc"))); - assert(_z_keyexpr_intersects("a/**/b$*", strlen("a/**/b$*"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_intersects("a/**/$*b$*", strlen("a/**/$*b$*"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_intersects("a/**/$*b", strlen("a/**/$*b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_intersects("a/**/b$*", strlen("a/**/b$*"), "a/bc", strlen("a/bc"))); - assert(_z_keyexpr_intersects("a/**/$*b$*", strlen("a/**/$*b$*"), "a/ebc", strlen("a/ebc"))); - assert(_z_keyexpr_intersects("a/**/$*b", strlen("a/**/$*b"), "a/cb", strlen("a/cb"))); - assert(_z_keyexpr_intersects("a/**/b/c/**/d", strlen("a/**/b/c/**/d"), "a/b/b/b/c/d", strlen("a/b/b/b/c/d"))); - assert( - !_z_keyexpr_intersects("a/**/b/c/**/d", strlen("a/**/b/c/**/d"), "a/b/b/b/c/@c/d", strlen("a/b/b/b/c/@c/d"))); - assert(!_z_keyexpr_intersects("a/**/b/c/**/d", strlen("a/**/b/c/**/d"), "a/b/@b/b/c/d", strlen("a/b/@b/b/c/d"))); - assert(_z_keyexpr_intersects("a/**/b/@b/**/b/c/**/d", strlen("a/**/b/@b/**/b/c/**/d"), "a/b/@b/b/c/d", - strlen("a/b/@b/b/c/d"))); - assert(!_z_keyexpr_intersects("a/**/b$*", strlen("a/**/b$*"), "a/ebc", strlen("a/ebc"))); - assert(!_z_keyexpr_intersects("a/**/$*b", strlen("a/**/$*b"), "a/cbc", strlen("a/cbc"))); - - assert(zp_keyexpr_intersect_null_terminated("a", "a")); - assert(zp_keyexpr_intersect_null_terminated("a/b", "a/b")); - assert(zp_keyexpr_intersect_null_terminated("*", "abc")); - assert(zp_keyexpr_intersect_null_terminated("*", "abc")); - assert(zp_keyexpr_intersect_null_terminated("*", "abc")); - assert(zp_keyexpr_intersect_null_terminated("*", "xxx")); - assert(zp_keyexpr_intersect_null_terminated("ab$*", "abcd")); - assert(zp_keyexpr_intersect_null_terminated("ab$*d", "abcd")); - assert(zp_keyexpr_intersect_null_terminated("ab$*", "ab")); - assert(!zp_keyexpr_intersect_null_terminated("ab/*", "ab")); - assert(zp_keyexpr_intersect_null_terminated("a/*/c/*/e", "a/b/c/d/e")); - assert(zp_keyexpr_intersect_null_terminated("a/**/d/**/l", "a/b/c/d/e/f/g/h/i/l")); - assert(zp_keyexpr_intersect_null_terminated("a/**/d/**/l", "a/d/foo/l")); - assert(zp_keyexpr_intersect_null_terminated("a/$*b/c/$*d/e", "a/xb/c/xd/e")); - assert(!zp_keyexpr_intersect_null_terminated("a/*/c/*/e", "a/c/e")); - assert(!zp_keyexpr_intersect_null_terminated("a/*/c/*/e", "a/b/c/d/x/e")); - assert(!zp_keyexpr_intersect_null_terminated("ab$*cd", "abxxcxxd")); - assert(zp_keyexpr_intersect_null_terminated("ab$*cd", "abxxcxxcd")); - assert(!zp_keyexpr_intersect_null_terminated("ab$*cd", "abxxcxxcdx")); - assert(zp_keyexpr_intersect_null_terminated("**", "abc")); - assert(zp_keyexpr_intersect_null_terminated("**", "a/b/c")); - assert(zp_keyexpr_intersect_null_terminated("ab/**", "ab")); - assert(zp_keyexpr_intersect_null_terminated("**/xyz", "a/b/xyz/d/e/f/xyz")); - assert(!zp_keyexpr_intersect_null_terminated("**/xyz$*xyz", "a/b/xyz/d/e/f/xyz")); - assert(zp_keyexpr_intersect_null_terminated("a/**/c/**/e", "a/b/b/b/c/d/d/d/e")); - assert(zp_keyexpr_intersect_null_terminated("a/**/c/**/e", "a/c/e")); - assert(zp_keyexpr_intersect_null_terminated("a/**/c/*/e/*", "a/b/b/b/c/d/d/c/d/e/f")); - assert(!zp_keyexpr_intersect_null_terminated("a/**/c/*/e/*", "a/b/b/b/c/d/d/c/d/d/e/f")); - assert(!zp_keyexpr_intersect_null_terminated("ab$*cd", "abxxcxxcdx")); - assert(zp_keyexpr_intersect_null_terminated("x/abc", "x/abc")); - assert(!zp_keyexpr_intersect_null_terminated("x/abc", "abc")); - assert(zp_keyexpr_intersect_null_terminated("x/*", "x/abc")); - assert(!zp_keyexpr_intersect_null_terminated("x/*", "abc")); - assert(!zp_keyexpr_intersect_null_terminated("*", "x/abc")); - assert(zp_keyexpr_intersect_null_terminated("x/*", "x/abc$*")); - assert(zp_keyexpr_intersect_null_terminated("x/$*abc", "x/abc$*")); - assert(zp_keyexpr_intersect_null_terminated("x/a$*", "x/abc$*")); - assert(zp_keyexpr_intersect_null_terminated("x/a$*de", "x/abc$*de")); - assert(zp_keyexpr_intersect_null_terminated("x/a$*d$*e", "x/a$*e")); - assert(zp_keyexpr_intersect_null_terminated("x/a$*d$*e", "x/a$*c$*e")); - assert(zp_keyexpr_intersect_null_terminated("x/a$*d$*e", "x/ade")); - assert(!zp_keyexpr_intersect_null_terminated("x/c$*", "x/abc$*")); - assert(!zp_keyexpr_intersect_null_terminated("x/$*d", "x/$*e")); - assert(zp_keyexpr_intersect_null_terminated("a", "a")); - assert(zp_keyexpr_intersect_null_terminated("a/b", "a/b")); - assert(zp_keyexpr_intersect_null_terminated("*", "a")); - assert(zp_keyexpr_intersect_null_terminated("a", "*")); - assert(zp_keyexpr_intersect_null_terminated("*", "aaaaa")); - assert(zp_keyexpr_intersect_null_terminated("**", "a")); - assert(zp_keyexpr_intersect_null_terminated("a", "**")); - assert(zp_keyexpr_intersect_null_terminated("**", "a")); - assert(zp_keyexpr_intersect_null_terminated("a/a/a/a", "**")); - assert(zp_keyexpr_intersect_null_terminated("a/*", "a/b")); - assert(!zp_keyexpr_intersect_null_terminated("a/*/b", "a/b")); - assert(zp_keyexpr_intersect_null_terminated("a/**/b", "a/b")); - assert(zp_keyexpr_intersect_null_terminated("a/b$*", "a/b")); - assert(zp_keyexpr_intersect_null_terminated("a/$*b$*", "a/b")); - assert(zp_keyexpr_intersect_null_terminated("a/$*b", "a/b")); - assert(zp_keyexpr_intersect_null_terminated("a/b$*", "a/bc")); - assert(zp_keyexpr_intersect_null_terminated("a/$*b$*", "a/ebc")); - assert(zp_keyexpr_intersect_null_terminated("a/$*b", "a/cb")); - assert(!zp_keyexpr_intersect_null_terminated("a/b$*", "a/ebc")); - assert(!zp_keyexpr_intersect_null_terminated("a/$*b", "a/cbc")); - assert(zp_keyexpr_intersect_null_terminated("a/**/b$*", "a/b")); - assert(zp_keyexpr_intersect_null_terminated("a/**/$*b$*", "a/b")); - assert(zp_keyexpr_intersect_null_terminated("a/**/$*b", "a/b")); - assert(zp_keyexpr_intersect_null_terminated("a/**/b$*", "a/bc")); - assert(zp_keyexpr_intersect_null_terminated("a/**/$*b$*", "a/ebc")); - assert(zp_keyexpr_intersect_null_terminated("a/**/$*b", "a/cb")); - assert(!zp_keyexpr_intersect_null_terminated("a/**/b$*", "a/ebc")); - assert(!zp_keyexpr_intersect_null_terminated("a/**/$*b", "a/cbc")); - - assert((zp_keyexpr_intersect_null_terminated("@a", "@a"))); - assert(!zp_keyexpr_intersect_null_terminated("@a", "@ab")); - assert(!zp_keyexpr_intersect_null_terminated("@a", "@a/b")); - assert(!zp_keyexpr_intersect_null_terminated("@a", "@a/*")); - assert(!zp_keyexpr_intersect_null_terminated("@a", "@a/*/**")); - assert(!zp_keyexpr_intersect_null_terminated("@a", "@a$*/**")); - assert((zp_keyexpr_intersect_null_terminated("@a", "@a/**"))); - assert(!zp_keyexpr_intersect_null_terminated("**/xyz$*xyz", "@a/b/xyzdefxyz")); - assert((zp_keyexpr_intersect_null_terminated("@a/**/c/**/e", "@a/b/b/b/c/d/d/d/e"))); - assert(!zp_keyexpr_intersect_null_terminated("@a/**/c/**/e", "@a/@b/b/b/c/d/d/d/e")); - assert((zp_keyexpr_intersect_null_terminated("@a/**/@c/**/e", "@a/b/b/b/@c/d/d/d/e"))); - assert((zp_keyexpr_intersect_null_terminated("@a/**/e", "@a/b/b/d/d/d/e"))); - assert((zp_keyexpr_intersect_null_terminated("@a/**/e", "@a/b/b/b/d/d/d/e"))); - assert((zp_keyexpr_intersect_null_terminated("@a/**/e", "@a/b/b/c/d/d/d/e"))); - assert(!zp_keyexpr_intersect_null_terminated("@a/**/e", "@a/b/b/@c/b/d/d/d/e")); - assert(!zp_keyexpr_intersect_null_terminated("@a/*", "@a/@b")); - assert(!zp_keyexpr_intersect_null_terminated("@a/**", "@a/@b")); - assert((zp_keyexpr_intersect_null_terminated("@a/**/@b", "@a/@b"))); - assert(!zp_keyexpr_intersect_null_terminated("@a/**/@b", "@a/**/@c/**/@b")); - assert((zp_keyexpr_intersect_null_terminated("@a/@b/**", "@a/@b"))); - assert((zp_keyexpr_intersect_null_terminated("@a/**/@c/@b", "@a/**/@c/**/@b"))); - assert((zp_keyexpr_intersect_null_terminated("@a/**/@c/**/@b", "@a/**/@c/@b"))); + _z_keyexpr_t ke_a, ke_b; + TEST_TRUE_INTERSECT("a", "a") + TEST_TRUE_INTERSECT("a/b", "a/b") + TEST_TRUE_INTERSECT("*", "abc") + TEST_TRUE_INTERSECT("*", "abc") + TEST_TRUE_INTERSECT("*", "abc") + TEST_TRUE_INTERSECT("*", "xxx") + TEST_TRUE_INTERSECT("ab$*", "abcd") + TEST_TRUE_INTERSECT("ab$*d", "abcd") + TEST_TRUE_INTERSECT("ab$*", "ab") + TEST_FALSE_INTERSECT("ab/*", "ab") + TEST_TRUE_INTERSECT("a/*/c/*/e", "a/b/c/d/e") + TEST_TRUE_INTERSECT("a/**/d/**/l", "a/b/c/d/e/f/g/h/i/l") + TEST_TRUE_INTERSECT("a/**/d/**/l", "a/d/foo/l") + TEST_TRUE_INTERSECT("a/$*b/c/$*d/e", "a/xb/c/xd/e") + TEST_FALSE_INTERSECT("a/*/c/*/e", "a/c/e") + TEST_FALSE_INTERSECT("a/*/c/*/e", "a/b/c/d/x/e") + TEST_FALSE_INTERSECT("ab$*cd", "abxxcxxd") + TEST_TRUE_INTERSECT("ab$*cd", "abxxcxxcd") + TEST_FALSE_INTERSECT("ab$*cd", "abxxcxxcdx") + TEST_TRUE_INTERSECT("**", "abc") + TEST_TRUE_INTERSECT("**", "a/b/c") + TEST_TRUE_INTERSECT("ab/**", "ab") + TEST_TRUE_INTERSECT("**/xyz", "a/b/xyz/d/e/f/xyz") + TEST_FALSE_INTERSECT("**/xyz$*xyz", "a/b/xyz/d/e/f/xyz") + TEST_TRUE_INTERSECT("a/**/c/**/e", "a/b/b/b/c/d/d/d/e") + TEST_TRUE_INTERSECT("a/**/c/**/e", "a/c/e") + TEST_TRUE_INTERSECT("a/**/c/*/e/*", "a/b/b/b/c/d/d/c/d/e/f") + TEST_FALSE_INTERSECT("a/**/c/*/e/*", "a/b/b/b/c/d/d/c/d/d/e/f") + TEST_FALSE_INTERSECT("ab$*cd", "abxxcxxcdx") + TEST_TRUE_INTERSECT("x/abc", "x/abc") + TEST_FALSE_INTERSECT("x/abc", "abc") + TEST_TRUE_INTERSECT("x/*", "x/abc") + TEST_FALSE_INTERSECT("x/*", "abc") + TEST_FALSE_INTERSECT("*", "x/abc") + TEST_TRUE_INTERSECT("x/*", "x/abc$*") + TEST_TRUE_INTERSECT("x/$*abc", "x/abc$*") + TEST_TRUE_INTERSECT("x/a$*", "x/abc$*") + TEST_TRUE_INTERSECT("x/a$*de", "x/abc$*de") + TEST_TRUE_INTERSECT("x/a$*d$*e", "x/a$*e") + TEST_TRUE_INTERSECT("x/a$*d$*e", "x/a$*c$*e") + TEST_TRUE_INTERSECT("x/a$*d$*e", "x/ade") + TEST_FALSE_INTERSECT("x/c$*", "x/abc$*") + TEST_FALSE_INTERSECT("x/$*d", "x/$*e") + TEST_TRUE_INTERSECT("a", "a") + TEST_TRUE_INTERSECT("a/b", "a/b") + TEST_TRUE_INTERSECT("*", "a") + TEST_TRUE_INTERSECT("a", "*") + TEST_TRUE_INTERSECT("*", "aaaaa") + TEST_TRUE_INTERSECT("**", "a") + TEST_TRUE_INTERSECT("a", "**") + TEST_TRUE_INTERSECT("**", "a") + TEST_TRUE_INTERSECT("a/a/a/a", "**") + TEST_TRUE_INTERSECT("a/*", "a/b") + TEST_FALSE_INTERSECT("a/*/b", "a/b") + TEST_TRUE_INTERSECT("a/**/b", "a/b") + TEST_TRUE_INTERSECT("a/b$*", "a/b") + TEST_TRUE_INTERSECT("a/$*b$*", "a/b") + TEST_TRUE_INTERSECT("a/$*b", "a/b") + TEST_TRUE_INTERSECT("a/b$*", "a/bc") + TEST_TRUE_INTERSECT("a/$*b$*", "a/ebc") + TEST_TRUE_INTERSECT("a/$*b", "a/cb") + TEST_FALSE_INTERSECT("a/b$*", "a/ebc") + TEST_FALSE_INTERSECT("a/$*b", "a/cbc") + TEST_TRUE_INTERSECT("a/**/b$*", "a/b") + TEST_TRUE_INTERSECT("a/**/$*b$*", "a/b") + TEST_TRUE_INTERSECT("a/**/$*b", "a/b") + TEST_TRUE_INTERSECT("a/**/b$*", "a/bc") + TEST_TRUE_INTERSECT("a/**/$*b$*", "a/ebc") + TEST_TRUE_INTERSECT("a/**/$*b", "a/cb") + TEST_FALSE_INTERSECT("a/**/b$*", "a/ebc") + TEST_FALSE_INTERSECT("a/**/$*b", "a/cbc") + + TEST_TRUE_INTERSECT("@a", "@a") + TEST_FALSE_INTERSECT("@a", "@ab") + TEST_FALSE_INTERSECT("@a", "@a/b") + TEST_FALSE_INTERSECT("@a", "@a/*") + TEST_FALSE_INTERSECT("@a", "@a/*/**") + TEST_FALSE_INTERSECT("@a", "@a$*/**") + TEST_TRUE_INTERSECT("@a", "@a/**") + TEST_FALSE_INTERSECT("**/xyz$*xyz", "@a/b/xyzdefxyz") + TEST_TRUE_INTERSECT("@a/**/c/**/e", "@a/b/b/b/c/d/d/d/e") + TEST_FALSE_INTERSECT("@a/**/c/**/e", "@a/@b/b/b/c/d/d/d/e") + TEST_TRUE_INTERSECT("@a/**/@c/**/e", "@a/b/b/b/@c/d/d/d/e") + TEST_TRUE_INTERSECT("@a/**/e", "@a/b/b/d/d/d/e") + TEST_TRUE_INTERSECT("@a/**/e", "@a/b/b/b/d/d/d/e") + TEST_TRUE_INTERSECT("@a/**/e", "@a/b/b/c/d/d/d/e") + TEST_FALSE_INTERSECT("@a/**/e", "@a/b/b/@c/b/d/d/d/e") + TEST_FALSE_INTERSECT("@a/*", "@a/@b") + TEST_FALSE_INTERSECT("@a/**", "@a/@b") + TEST_TRUE_INTERSECT("@a/**/@b", "@a/@b") + TEST_FALSE_INTERSECT("@a/**/@b", "@a/**/@c/**/@b") + TEST_TRUE_INTERSECT("@a/@b/**", "@a/@b") + TEST_TRUE_INTERSECT("@a/**/@c/@b", "@a/**/@c/**/@b") + TEST_TRUE_INTERSECT("@a/**/@c/**/@b", "@a/**/@c/@b") } void test_includes(void) { - assert(_z_keyexpr_includes("a", strlen("a"), "a", strlen("a"))); - assert(_z_keyexpr_includes("a/b", strlen("a/b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_includes("*", strlen("*"), "a", strlen("a"))); - assert(!_z_keyexpr_includes("a", strlen("a"), "*", strlen("*"))); - assert(_z_keyexpr_includes("*", strlen("*"), "aaaaa", strlen("aaaaa"))); - assert(_z_keyexpr_includes("**", strlen("**"), "a", strlen("a"))); - assert(!_z_keyexpr_includes("a", strlen("a"), "**", strlen("**"))); - assert(_z_keyexpr_includes("**", strlen("**"), "a", strlen("a"))); - assert(_z_keyexpr_includes("**", strlen("**"), "a/a/a/a", strlen("a/a/a/a"))); - assert(_z_keyexpr_includes("**", strlen("**"), "*/**", strlen("*/**"))); - assert(_z_keyexpr_includes("*/**", strlen("*/**"), "*/**", strlen("*/**"))); - assert(!_z_keyexpr_includes("*/**", strlen("*/**"), "**", strlen("**"))); - assert(!_z_keyexpr_includes("a/a/a/a", strlen("a/a/a/a"), "**", strlen("**"))); - assert(_z_keyexpr_includes("a/*", strlen("a/*"), "a/b", strlen("a/b"))); - assert(!_z_keyexpr_includes("a/*/b", strlen("a/*/b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_includes("a/**/b", strlen("a/**/b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_includes("a/b$*", strlen("a/b$*"), "a/b", strlen("a/b"))); - assert(!_z_keyexpr_includes("a/b", strlen("a/b"), "a/b$*", strlen("a/b$*"))); - assert(_z_keyexpr_includes("a/$*b$*", strlen("a/$*b$*"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_includes("a/$*b", strlen("a/$*b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_includes("a/b$*", strlen("a/b$*"), "a/bc", strlen("a/bc"))); - assert(_z_keyexpr_includes("a/$*b$*", strlen("a/$*b$*"), "a/ebc", strlen("a/ebc"))); - assert(_z_keyexpr_includes("a/$*b", strlen("a/$*b"), "a/cb", strlen("a/cb"))); - assert(!_z_keyexpr_includes("a/b$*", strlen("a/b$*"), "a/ebc", strlen("a/ebc"))); - assert(!_z_keyexpr_includes("a/$*b", strlen("a/$*b"), "a/cbc", strlen("a/cbc"))); - assert(_z_keyexpr_includes("a/**/b$*", strlen("a/**/b$*"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_includes("a/**/$*b$*", strlen("a/**/$*b$*"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_includes("a/**/$*b", strlen("a/**/$*b"), "a/b", strlen("a/b"))); - assert(_z_keyexpr_includes("a/**/b$*", strlen("a/**/b$*"), "a/bc", strlen("a/bc"))); - assert(_z_keyexpr_includes("a/**/$*b$*", strlen("a/**/$*b$*"), "a/ebc", strlen("a/ebc"))); - assert(_z_keyexpr_includes("a/**/$*b", strlen("a/**/$*b"), "a/cb", strlen("a/cb"))); - assert(!_z_keyexpr_includes("a/**/b$*", strlen("a/**/b$*"), "a/ebc", strlen("a/ebc"))); - assert(!_z_keyexpr_includes("a/**/$*b", strlen("a/**/$*b"), "a/cbc", strlen("a/cbc"))); - - assert(zp_keyexpr_includes_null_terminated("a", "a")); - assert(zp_keyexpr_includes_null_terminated("a/b", "a/b")); - assert(zp_keyexpr_includes_null_terminated("*", "a")); - assert(!zp_keyexpr_includes_null_terminated("a", "*")); - assert(zp_keyexpr_includes_null_terminated("*", "aaaaa")); - assert(zp_keyexpr_includes_null_terminated("**", "a")); - assert(!zp_keyexpr_includes_null_terminated("a", "**")); - assert(zp_keyexpr_includes_null_terminated("**", "a")); - assert(zp_keyexpr_includes_null_terminated("**", "a/a/a/a")); - assert(zp_keyexpr_includes_null_terminated("**", "*/**")); - assert(zp_keyexpr_includes_null_terminated("*/**", "*/**")); - assert(!zp_keyexpr_includes_null_terminated("*/**", "**")); - assert(!zp_keyexpr_includes_null_terminated("a/a/a/a", "**")); - assert(zp_keyexpr_includes_null_terminated("a/*", "a/b")); - assert(!zp_keyexpr_includes_null_terminated("a/*/b", "a/b")); - assert(zp_keyexpr_includes_null_terminated("a/**/b", "a/b")); - assert(zp_keyexpr_includes_null_terminated("a/b$*", "a/b")); - assert(!zp_keyexpr_includes_null_terminated("a/b", "a/b$*")); - assert(zp_keyexpr_includes_null_terminated("a/$*b$*", "a/b")); - assert(zp_keyexpr_includes_null_terminated("a/$*b", "a/b")); - assert(zp_keyexpr_includes_null_terminated("a/b$*", "a/bc")); - assert(zp_keyexpr_includes_null_terminated("a/$*b$*", "a/ebc")); - assert(zp_keyexpr_includes_null_terminated("a/$*b", "a/cb")); - assert(!zp_keyexpr_includes_null_terminated("a/b$*", "a/ebc")); - assert(!zp_keyexpr_includes_null_terminated("a/$*b", "a/cbc")); - assert(zp_keyexpr_includes_null_terminated("a/**/b$*", "a/b")); - assert(zp_keyexpr_includes_null_terminated("a/**/$*b$*", "a/b")); - assert(zp_keyexpr_includes_null_terminated("a/**/$*b", "a/b")); - assert(zp_keyexpr_includes_null_terminated("a/**/b$*", "a/bc")); - assert(zp_keyexpr_includes_null_terminated("a/**/$*b$*", "a/ebc")); - assert(zp_keyexpr_includes_null_terminated("a/**/$*b", "a/cb")); - assert(!zp_keyexpr_includes_null_terminated("a/**/b$*", "a/ebc")); - assert(!zp_keyexpr_includes_null_terminated("a/**/$*b", "a/cbc")); - - assert((zp_keyexpr_includes_null_terminated("@a", "@a"))); - assert(!zp_keyexpr_includes_null_terminated("@a", "@ab")); - assert(!zp_keyexpr_includes_null_terminated("@a", "@a/b")); - assert(!zp_keyexpr_includes_null_terminated("@a", "@a/*")); - assert(!zp_keyexpr_includes_null_terminated("@a", "@a/*/**")); - assert(!zp_keyexpr_includes_null_terminated("@a$*/**", "@a")); - assert(!zp_keyexpr_includes_null_terminated("@a", "@a/**")); - assert((zp_keyexpr_includes_null_terminated("@a/**", "@a"))); - assert(!zp_keyexpr_includes_null_terminated("**/xyz$*xyz", "@a/b/xyzdefxyz")); - assert((zp_keyexpr_includes_null_terminated("@a/**/c/**/e", "@a/b/b/b/c/d/d/d/e"))); - assert(!zp_keyexpr_includes_null_terminated("@a/*", "@a/@b")); - assert(!zp_keyexpr_includes_null_terminated("@a/**", "@a/@b")); - assert((zp_keyexpr_includes_null_terminated("@a/**/@b", "@a/@b"))); - assert((zp_keyexpr_includes_null_terminated("@a/@b/**", "@a/@b"))); + _z_keyexpr_t ke_a, ke_b; + TEST_TRUE_INCLUDE("a", "a") + TEST_TRUE_INCLUDE("a/b", "a/b") + TEST_TRUE_INCLUDE("*", "a") + TEST_FALSE_INCLUDE("a", "*") + TEST_TRUE_INCLUDE("*", "aaaaa") + TEST_TRUE_INCLUDE("**", "a") + TEST_FALSE_INCLUDE("a", "**") + TEST_TRUE_INCLUDE("**", "a") + TEST_TRUE_INCLUDE("**", "a/a/a/a") + TEST_TRUE_INCLUDE("**", "*/**") + TEST_TRUE_INCLUDE("*/**", "*/**") + TEST_FALSE_INCLUDE("*/**", "**") + TEST_FALSE_INCLUDE("a/a/a/a", "**") + TEST_TRUE_INCLUDE("a/*", "a/b") + TEST_FALSE_INCLUDE("a/*/b", "a/b") + TEST_TRUE_INCLUDE("a/**/b", "a/b") + TEST_TRUE_INCLUDE("a/b$*", "a/b") + TEST_FALSE_INCLUDE("a/b", "a/b$*") + TEST_TRUE_INCLUDE("a/$*b$*", "a/b") + TEST_TRUE_INCLUDE("a/$*b", "a/b") + TEST_TRUE_INCLUDE("a/b$*", "a/bc") + TEST_TRUE_INCLUDE("a/$*b$*", "a/ebc") + TEST_TRUE_INCLUDE("a/$*b", "a/cb") + TEST_FALSE_INCLUDE("a/b$*", "a/ebc") + TEST_FALSE_INCLUDE("a/$*b", "a/cbc") + TEST_TRUE_INCLUDE("a/**/b$*", "a/b") + TEST_TRUE_INCLUDE("a/**/$*b$*", "a/b") + TEST_TRUE_INCLUDE("a/**/$*b", "a/b") + TEST_TRUE_INCLUDE("a/**/b$*", "a/bc") + TEST_TRUE_INCLUDE("a/**/$*b$*", "a/ebc") + TEST_TRUE_INCLUDE("a/**/$*b", "a/cb") + TEST_FALSE_INCLUDE("a/**/b$*", "a/ebc") + TEST_FALSE_INCLUDE("a/**/$*b", "a/cbc") + + TEST_TRUE_INCLUDE("@a", "@a") + TEST_FALSE_INCLUDE("@a", "@ab") + TEST_FALSE_INCLUDE("@a", "@a/b") + TEST_FALSE_INCLUDE("@a", "@a/*") + TEST_FALSE_INCLUDE("@a", "@a/*/**") + TEST_FALSE_INCLUDE("@a$*/**", "@a") + TEST_FALSE_INCLUDE("@a", "@a/**") + TEST_TRUE_INCLUDE("@a/**", "@a") + TEST_FALSE_INCLUDE("**/xyz$*xyz", "@a/b/xyzdefxyz") + TEST_TRUE_INCLUDE("@a/**/c/**/e", "@a/b/b/b/c/d/d/d/e") + TEST_FALSE_INCLUDE("@a/*", "@a/@b") + TEST_FALSE_INCLUDE("@a/**", "@a/@b") + TEST_TRUE_INCLUDE("@a/**/@b", "@a/@b") + TEST_TRUE_INCLUDE("@a/@b/**", "@a/@b") } void test_canonize(void) { @@ -408,28 +322,30 @@ void test_canonize(void) { memset(canon, 0, 128); strncpy(canon, ke, 128); size_t canon_len = strlen(canon); - zp_keyexpr_canon_status_t status = zp_keyexpr_canonize_null_terminated(canon); + zp_keyexpr_canon_status_t status = z_keyexpr_canonize(canon, &canon_len); printf("%s ", ke); printf(" Status: %d : %d", status, expected[i]); assert(status == expected[i]); if (status == Z_KEYEXPR_CANON_SUCCESS) { printf(" Match: %.*s : %s", (int)canon_len, canon, canonized[i]); - assert(strcmp(canonized[i], canon) == 0); + assert(strncmp(canonized[i], canon, canon_len) == 0); } printf("\n"); } } void test_equals(void) { - assert(!zp_keyexpr_equals_null_terminated("a/**/$*b", "a/cb")); - assert(!zp_keyexpr_equals_null_terminated("a/bc", "a/cb")); - assert(zp_keyexpr_equals_null_terminated("greetings/hello/there", "greetings/hello/there")); + _z_keyexpr_t ke_a, ke_b; + TEST_FALSE_EQUAL("a/**/$*b", "a/cb"); + TEST_FALSE_EQUAL("a/bc", "a/cb"); + TEST_TRUE_EQUAL("greetings/hello/there", "greetings/hello/there"); } _Bool keyexpr_equals_string(const z_loaned_keyexpr_t *ke, const char *s) { z_view_string_t vs; z_keyexpr_as_view_string(ke, &vs); - return strncmp(z_string_data(z_view_string_loan(&vs)), s, z_string_len(z_view_string_loan(&vs))) == 0; + _z_string_t str = _z_string_from_str(s); + return _z_string_equals(z_view_string_loan(&vs), &str); } void test_keyexpr_constructor(void) { diff --git a/tests/z_msgcodec_test.c b/tests/z_msgcodec_test.c index fce61c2bf..a2ed5b990 100644 --- a/tests/z_msgcodec_test.c +++ b/tests/z_msgcodec_test.c @@ -237,8 +237,8 @@ _z_locator_array_t gen_locator_array(size_t size) { _z_locator_array_t la = _z_locator_array_make(size); for (size_t i = 0; i < size; i++) { _z_locator_t *val = &la._val[i]; - val->_protocol = gen_str(3); - val->_address = gen_str(12); + val->_protocol = gen_string(3); + val->_address = gen_string(12); val->_metadata = _z_str_intmap_make(); // @TODO: generate metadata } @@ -308,7 +308,7 @@ void assert_eq_uint8_array(const _z_slice_t *left, const _z_slice_t *right) { printf(")"); } -void assert_eq_str_array(_z_string_svec_t *left, _z_string_svec_t *right) { +void assert_eq_string_array(_z_string_svec_t *left, _z_string_svec_t *right) { printf("Array -> "); printf("Length (%zu:%zu), ", left->_len, right->_len); @@ -317,11 +317,13 @@ void assert_eq_str_array(_z_string_svec_t *left, _z_string_svec_t *right) { for (size_t i = 0; i < left->_len; i++) { const char *l = _z_string_data(_z_string_svec_get(left, i)); const char *r = _z_string_data(_z_string_svec_get(right, i)); + size_t l_len = _z_string_len(_z_string_svec_get(left, i)); + size_t r_len = _z_string_len(_z_string_svec_get(right, i)); - printf("%s:%s", l, r); + printf("%.*s:%.*s", (int)l_len, l, (int)r_len, r); if (i < left->_len - 1) printf(" "); - assert(_z_str_eq(l, r) == true); + assert(_z_string_equals(_z_string_svec_get(left, i), _z_string_svec_get(right, i))); } printf(")"); } @@ -510,7 +512,7 @@ void assert_eq_slice(const _z_slice_t *left, const _z_slice_t *right) { assert_e void assert_eq_string(const _z_string_t *left, const _z_string_t *right) { assert(_z_string_len(left) == _z_string_len(right)); if (_z_string_len(left) > 0) { - assert(_z_str_eq(_z_string_data(left), _z_string_data(right)) == true); + assert(_z_string_equals(left, right)); } } @@ -661,11 +663,13 @@ _z_keyexpr_t gen_keyexpr(void) { key._mapping._val = gen_uint8(); _Bool is_numerical = gen_bool(); if (is_numerical == true) { - key._suffix = NULL; - _z_keyexpr_set_owns_suffix(&key, false); + key._suffix = _z_string_null(); } else { - key._suffix = gen_str(gen_zint() % 16); - _z_keyexpr_set_owns_suffix(&key, true); + size_t len = gen_zint() % 16; + key._suffix = _z_string_preallocate(len); + char *suffix = gen_str(len); + memcpy((char *)_z_string_data(&key._suffix), suffix, len); + z_free(suffix); } return key; } @@ -674,12 +678,13 @@ void assert_eq_keyexpr(const _z_keyexpr_t *left, const _z_keyexpr_t *right) { printf("ResKey -> "); printf("ID (%u:%u), ", left->_id, right->_id); assert(left->_id == right->_id); - assert(!(_z_keyexpr_has_suffix(*left) ^ _z_keyexpr_has_suffix(*right))); + assert(_z_keyexpr_has_suffix(left) == _z_keyexpr_has_suffix(right)); printf("Name ("); - if (_z_keyexpr_has_suffix(*left)) { - printf("%s:%s", left->_suffix, right->_suffix); - assert(_z_str_eq(left->_suffix, right->_suffix) == true); + if (_z_keyexpr_has_suffix(left)) { + printf("%.*s:%.*s", (int)_z_string_len(&left->_suffix), _z_string_data(&left->_suffix), + (int)_z_string_len(&right->_suffix), _z_string_data(&right->_suffix)); + assert(_z_string_equals(&left->_suffix, &right->_suffix) == true); } else { printf("NULL:NULL"); } @@ -694,7 +699,7 @@ void keyexpr_field(void) { _z_keyexpr_t e_rk = gen_keyexpr(); // Encode - uint8_t header = (e_rk._suffix) ? _Z_FLAG_Z_K : 0; + uint8_t header = (_z_keyexpr_has_suffix(&e_rk)) ? _Z_FLAG_Z_K : 0; int8_t res = _z_keyexpr_encode(&wbf, _Z_HAS_FLAG(header, _Z_FLAG_Z_K), &e_rk); assert(res == _Z_RES_OK); (void)(res); @@ -929,7 +934,6 @@ void forget_subscriber_declaration(void) { _z_uint8_decode(&e_hdr, &zbf); res = _z_undecl_subscriber_decode(&d_fsd, &zbf, e_hdr); assert(res == _Z_RES_OK); - printf(" "); assert_eq_forget_subscriber_declaration(&e_fsd, &d_fsd); printf("\n"); @@ -1137,9 +1141,10 @@ _z_network_message_t gen_interest_message(void) { void assert_eq_interest(const _z_interest_t *left, const _z_interest_t *right) { printf("Interest: 0x%x, 0x%x, %u, %u\n", left->flags, right->flags, left->_id, right->_id); - printf("Interest ke: %d, %d, %d, %d, %s, %s\n", left->_keyexpr._id, right->_keyexpr._id, - left->_keyexpr._mapping._val, right->_keyexpr._mapping._val, left->_keyexpr._suffix, - right->_keyexpr._suffix); + printf("Interest ke: %d, %d, %d, %d, %.*s, %.*s\n", left->_keyexpr._id, right->_keyexpr._id, + left->_keyexpr._mapping._val, right->_keyexpr._mapping._val, (int)_z_string_len(&left->_keyexpr._suffix), + _z_string_data(&left->_keyexpr._suffix), (int)_z_string_len(&right->_keyexpr._suffix), + _z_string_data(&right->_keyexpr._suffix)); assert(left->flags == right->flags); assert(left->_id == right->_id); assert_eq_keyexpr(&left->_keyexpr, &right->_keyexpr); diff --git a/tests/z_peer_multicast_test.c b/tests/z_peer_multicast_test.c index 7966eb820..89efd3f49 100644 --- a/tests/z_peer_multicast_test.c +++ b/tests/z_peer_multicast_test.c @@ -45,7 +45,6 @@ void data_handler(const z_loaned_sample_t *sample, void *arg) { char *res = (char *)malloc(64); snprintf(res, 64, "%s%u", uri, *(unsigned int *)arg); printf(">> Received data: %s\t(%u/%u)\n", res, datas, total); - z_view_string_t k_str; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &k_str); z_owned_slice_t value; diff --git a/tests/z_test_fragment_rx.c b/tests/z_test_fragment_rx.c index 744b915e2..056b9f5ba 100644 --- a/tests/z_test_fragment_rx.c +++ b/tests/z_test_fragment_rx.c @@ -33,9 +33,9 @@ void data_handler(const z_loaned_sample_t *sample, void *ctx) { break; } } - printf("[rx]: Received packet on %s, len: %d, validity: %d, qos {priority: %d, cong_ctrl: %d}\n", - z_string_data(z_loan(keystr)), (int)data_len, is_valid, z_sample_priority(sample), - z_sample_congestion_control(sample)); + printf("[rx]: Received packet on %.*s, len: %d, validity: %d, qos {priority: %d, cong_ctrl: %d}\n", + (int)z_string_len(z_loan(keystr)), z_string_data(z_loan(keystr)), (int)data_len, is_valid, + z_sample_priority(sample), z_sample_congestion_control(sample)); z_drop(z_move(value)); } diff --git a/tools/z_keyexpr_canonizer.c b/tools/z_keyexpr_canonizer.c index 239152648..3ffd19105 100644 --- a/tools/z_keyexpr_canonizer.c +++ b/tools/z_keyexpr_canonizer.c @@ -33,7 +33,7 @@ int main(int argc, char **argv) { buffer = realloc(buffer, len + 1); strncpy(buffer, argv[i], len); buffer[len] = '\0'; - zp_keyexpr_canon_status_t status = zp_keyexpr_canonize_null_terminated(buffer); + zp_keyexpr_canon_status_t status = z_keyexpr_canonize(buffer, &len); switch (status) { case Z_KEYEXPR_CANON_SUCCESS: