diff --git a/docs/api.rst b/docs/api.rst index a3d829ab7..3119d6cea 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -296,6 +296,7 @@ Primitives .. autocfunction:: primitives.h::z_view_string_wrap .. autocfunction:: primitives.h::z_view_keyexpr_from_str .. autocfunction:: primitives.h::z_view_keyexpr_from_str_unchecked +.. autocfunction:: primitives.h::z_view_keyexpr_from_str_autocanonize .. autocfunction:: primitives.h::z_keyexpr_to_string .. autocfunction:: primitives.h::zp_keyexpr_resolve .. autocfunction:: primitives.h::z_keyexpr_is_initialized diff --git a/include/zenoh-pico/api/primitives.h b/include/zenoh-pico/api/primitives.h index c63732b2d..cc0f3f5b5 100644 --- a/include/zenoh-pico/api/primitives.h +++ b/include/zenoh-pico/api/primitives.h @@ -73,6 +73,22 @@ int8_t z_view_keyexpr_from_str(z_view_keyexpr_t *keyexpr, const char *name); */ int8_t z_view_keyexpr_from_str_unchecked(z_view_keyexpr_t *keyexpr, const char *name); +/** + * Builds a :c:type:`z_keyexpr_t` from a null-terminated string with auto canonization. + * It is a loaned key expression that aliases ``name``. + * The string is canonized in-place before being passed to keyexpr, possibly shortening it by modifying len. + * May SEGFAULT if `name` is NULL or lies in read-only memory (as values initialized with string litterals do). + * `name` must outlive the constucted key expression. + * + * Parameters: + * name: Pointer to string representation of the keyexpr as a null terminated string. + * keyexpr: Pointer to an uninitialized :c:type:`z_view_keyexpr_t`. + * + * Return: + * ``0`` if creation successful, ``negative value`` otherwise. + */ +int8_t z_view_keyexpr_from_str_autocanonize(z_view_keyexpr_t *keyexpr, char *name); + /** * Gets a null-terminated string from a :c:type:`z_keyexpr_t`. * diff --git a/src/api/api.c b/src/api/api.c index aec73a739..e0032c25d 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -59,11 +59,30 @@ 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'; + } + + return ret; +} + int8_t z_view_keyexpr_from_str(z_view_keyexpr_t *keyexpr, const char *name) { keyexpr->_val = _z_rname(name); return _Z_RES_OK; } +int8_t z_view_keyexpr_from_str_autocanonize(z_view_keyexpr_t *keyexpr, char *name) { + zp_keyexpr_canonize_null_terminated(name); + keyexpr->_val = _z_rname(name); + return _Z_RES_OK; +} + int8_t z_view_keyexpr_from_str_unchecked(z_view_keyexpr_t *keyexpr, const char *name) { keyexpr->_val = _z_rname(name); return _Z_RES_OK; @@ -107,19 +126,6 @@ int8_t zp_keyexpr_is_canon_null_terminated(const char *start) { return _z_keyexp int8_t z_keyexpr_canonize(char *start, size_t *len) { return _z_keyexpr_canonize(start, len); } -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'; - } - - return ret; -} - _Bool z_keyexpr_includes(const z_loaned_keyexpr_t *l, const z_loaned_keyexpr_t *r) { if ((l->_id == Z_RESOURCE_ID_NONE) && (r->_id == Z_RESOURCE_ID_NONE)) { return zp_keyexpr_includes_null_terminated(l->_suffix, r->_suffix);