Skip to content

Commit

Permalink
add z_(owned_)keyexpr_t autocanonize initializers
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisBiryukov91 committed Mar 11, 2024
1 parent 10176b9 commit 0e3e3d4
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ Key expression
.. autocstruct:: zenoh_commons.h::z_owned_keyexpr_t

.. autocfunction:: zenoh_commons.h::z_keyexpr
.. autocfunction:: zenoh_commons.h::z_keyexpr_autocanonize
.. autocfunction:: zenoh_commons.h::z_keyexpr_unchecked
.. autocfunction:: zenoh_commons.h::z_keyexpr_to_string
.. autocfunction:: zenoh_commons.h::z_keyexpr_as_bytes
Expand All @@ -120,6 +121,7 @@ Key expression
.. autocfunction:: zenoh_commons.h::z_keyexpr_intersects

.. autocfunction:: zenoh_commons.h::z_keyexpr_new
.. autocfunction:: zenoh_commons.h::z_keyexpr_new_autocanonize
.. autocfunction:: zenoh_commons.h::z_keyexpr_loan
.. autocfunction:: zenoh_commons.h::z_keyexpr_check
.. autocfunction:: zenoh_commons.h::z_keyexpr_drop
Expand Down
22 changes: 22 additions & 0 deletions include/zenoh_commons.h
Original file line number Diff line number Diff line change
Expand Up @@ -1551,6 +1551,14 @@ ZENOHC_API struct z_keyexpr_t z_keyexpr(const char *name);
* Currently exclusive to zenoh-c
*/
ZENOHC_API struct z_bytes_t z_keyexpr_as_bytes(struct z_keyexpr_t keyexpr);
/**
* Constructs a :c:type:`z_keyexpr_t` departing from a string.
* It is a loaned key expression that aliases `name`.
* The string is canonized in-place before being passed to keyexpr.
* May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do).
*/
ZENOHC_API
struct z_keyexpr_t z_keyexpr_autocanonize(char *name);
/**
* Canonizes the passed string in place, possibly shortening it by modifying `len`.
*
Expand Down Expand Up @@ -1639,6 +1647,11 @@ ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key
* Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string.
*/
ZENOHC_API struct z_owned_keyexpr_t z_keyexpr_new(const char *name);
/**
* Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized.
*/
ZENOHC_API
struct z_owned_keyexpr_t z_keyexpr_new_autocanonize(const char *name);
/**
* Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type
*/
Expand Down Expand Up @@ -2174,6 +2187,15 @@ ZENOHC_API void zc_init_logger(void);
* It is a loaned key expression that aliases `name`.
*/
ZENOHC_API struct z_keyexpr_t zc_keyexpr_from_slice(const char *name, size_t len);
/**
* Constructs a :c:type:`z_keyexpr_t` departing from a string.
* It is a loaned key expression that aliases `name`.
* The string is canonized in-place before being passed to keyexpr.
* May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do).
*/
ZENOHC_API
struct z_keyexpr_t zc_keyexpr_from_slice_autocanonize(char *name,
size_t *len);
/**
* Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions:
* - `name` MUST be valid UTF8.
Expand Down
56 changes: 56 additions & 0 deletions src/keyexpr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,32 @@ pub unsafe extern "C" fn z_keyexpr_new(name: *const c_char) -> z_owned_keyexpr_t
}
}

/// Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized.
#[allow(clippy::missing_safety_doc)]
#[no_mangle]
pub unsafe extern "C" fn z_keyexpr_new_autocanonize(name: *const c_char) -> z_owned_keyexpr_t {
if name.is_null() {
return z_owned_keyexpr_t::null();
}
let name = std::slice::from_raw_parts(name as _, libc::strlen(name));
match std::str::from_utf8(name) {
Ok(name) => {
let name_owned = name.to_owned();
match KeyExpr::autocanonize(name_owned) {
Ok(v) => v.into_owned().into(),
Err(e) => {
log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e);
z_owned_keyexpr_t::null()
}
}
}
Err(e) => {
log::error!("{}", e);
z_owned_keyexpr_t::null()
}
}
}

/// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`.
#[no_mangle]
pub extern "C" fn z_keyexpr_loan(keyexpr: &z_owned_keyexpr_t) -> z_keyexpr_t {
Expand Down Expand Up @@ -309,6 +335,22 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice(name: *const c_char, len: usize)
}
}

/// Constructs a :c:type:`z_keyexpr_t` departing from a string.
/// It is a loaned key expression that aliases `name`.
/// The string is canonized in-place before being passed to keyexpr.
/// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do).
#[allow(clippy::missing_safety_doc)]
#[no_mangle]
pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize(
name: *mut c_char,
len: &mut usize,
) -> z_keyexpr_t {
if z_keyexpr_canonize(name, len) < 0 {
return z_keyexpr_t::null();
}
zc_keyexpr_from_slice(name, *len)
}

/// Constructs a :c:type:`z_keyexpr_t` departing from a string.
/// It is a loaned key expression that aliases `name`.
#[allow(clippy::missing_safety_doc)]
Expand All @@ -321,6 +363,20 @@ pub unsafe extern "C" fn z_keyexpr(name: *const c_char) -> z_keyexpr_t {
}
}

/// Constructs a :c:type:`z_keyexpr_t` departing from a string.
/// It is a loaned key expression that aliases `name`.
/// The string is canonized in-place before being passed to keyexpr.
/// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do).
#[allow(clippy::missing_safety_doc)]
#[no_mangle]
pub unsafe extern "C" fn z_keyexpr_autocanonize(name: *mut c_char) -> z_keyexpr_t {
if name.is_null() || z_keyexpr_canonize_null_terminated(name) < 0 {
z_keyexpr_t::null()
} else {
z_keyexpr(name)
}
}

/// Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions:
/// - `name` MUST be valid UTF8.
/// - `name` MUST follow the Key Expression specification, ie:
Expand Down
16 changes: 16 additions & 0 deletions tests/z_api_keyexpr_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@ void canonize() {
printf("'%s', err = %d\n", keyexpr, err);
assert(err == 0);
assert(strcmp(keyexpr, "a/**/c") == 0);

strcpy(keyexpr, "a/**/**/c");
z_keyexpr_t key_expr_canonized = z_keyexpr_autocanonize(keyexpr);
assert(z_keyexpr_check(keyexpr) == true);
assert(strcmp(keyexpr, "a/**/c") == 0);
assert(z_keyexpr_as_bytes(key_expr_canonized).len == len_new);
assert(strncmp(z_keyexpr_as_bytes(key_expr_canonized).start, "a/**/c", len_new) == 0);

strcpy(keyexpr, "a/**/**/c");
len_new = len_old;
key_expr_canonized = zc_keyexpr_from_slice_autocanonize(keyexpr, &len_new);
assert(z_keyexpr_check(keyexpr) == true);
assert(len_new == len_old - 3);
assert(strncmp(keyexpr, "a/**/c", len_new) == 0);
assert(z_keyexpr_as_bytes(key_expr_canonized).len == len_new);
assert(strncmp(z_keyexpr_as_bytes(key_expr_canonized).start, "a/**/c", len_new) == 0);
}

void includes() {
Expand Down

0 comments on commit 0e3e3d4

Please sign in to comment.