From b447b299691d8969054951a5011de2a8863e50e9 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 12 Mar 2024 18:57:25 +0100 Subject: [PATCH 1/2] add z_whatami_to_str api --- examples/z_scout.c | 12 +++++------- include/zenoh_commons.h | 12 ++++++++++++ src/lib.rs | 27 +++++++++++++++++++++++++++ src/platform/clock.rs | 12 ++++-------- src/scouting.rs | 31 +++++++++++++++++++++++++++++-- 5 files changed, 77 insertions(+), 17 deletions(-) diff --git a/examples/z_scout.c b/examples/z_scout.c index 8dffaab7f..8398bf1fe 100644 --- a/examples/z_scout.c +++ b/examples/z_scout.c @@ -33,13 +33,11 @@ void fprintpid(FILE *stream, z_id_t pid) { } void fprintwhatami(FILE *stream, unsigned int whatami) { - if (whatami == Z_ROUTER) { - fprintf(stream, "\"Router\""); - } else if (whatami == Z_PEER) { - fprintf(stream, "\"Peer\""); - } else { - fprintf(stream, "\"Other\""); - } + char buf[64]; + z_time_now_as_str(buf, sizeof(buf)); + fprintf(stream, "%s", buf); + z_whatami_to_str(whatami, buf, sizeof(buf)); + fprintf(stream, "%s", buf); } void fprintlocators(FILE *stream, const z_str_array_t *locs) { diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index cafca6456..04cca290a 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -2129,6 +2129,18 @@ ZENOHC_API int8_t z_undeclare_queryable(struct z_owned_queryable_t *qable); */ ZENOHC_API int8_t z_undeclare_subscriber(struct z_owned_subscriber_t *sub); +/** + * Converts the kind of zenoh entity into a string. + * + * Parameters: + * whatami: A whatami bitmask of zenoh entity kind. + * buf: Buffer to write a null-terminated string to. + * len: Maximum number of bytes that can be written to the `buf`. + * + * Returns 0 if successful, negative values if whatami contains an invalid bitmask or `buf` is null, + * or number of remaining bytes, if the null-terminated string size exceeds `len`. + */ +ZENOHC_API int8_t z_whatami_to_str(uint8_t whatami, char *buf, size_t len); /** * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. */ diff --git a/src/lib.rs b/src/lib.rs index 718475444..de6584885 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,9 @@ #![allow(non_camel_case_types)] mod collections; +use std::cmp::min; +use std::slice; + pub use crate::collections::*; mod config; pub use crate::config::*; @@ -43,6 +46,7 @@ pub use crate::publisher::*; mod closures; pub use closures::*; mod liveliness; +use libc::c_void; pub use liveliness::*; mod publication_cache; pub use publication_cache::*; @@ -122,3 +126,26 @@ fn test_no_default_features() { ) ); } + +trait CopyableToCArray { + fn copy_to_c_array(&self, buf: *mut c_void, len: usize) -> usize; +} + +impl CopyableToCArray for &[u8] { + fn copy_to_c_array(&self, buf: *mut c_void, len: usize) -> usize { + if buf.is_null() || (len == 0 && !self.is_empty()) { + return 0; + } + + let max_len = min(len, self.len()); + let b = unsafe { slice::from_raw_parts_mut(buf as *mut u8, max_len) }; + b[0..max_len].copy_from_slice(&self[0..max_len]); + max_len + } +} + +impl CopyableToCArray for &str { + fn copy_to_c_array(&self, buf: *mut c_void, len: usize) -> usize { + self.as_bytes().copy_to_c_array(buf, len) + } +} diff --git a/src/platform/clock.rs b/src/platform/clock.rs index 3f2c91c17..196d697cb 100644 --- a/src/platform/clock.rs +++ b/src/platform/clock.rs @@ -1,12 +1,11 @@ use chrono::{DateTime, Local}; use libc::c_char; use std::{ - cmp::min, os::raw::c_void, - slice, time::{Duration, Instant, SystemTime, UNIX_EPOCH}, }; +use crate::CopyableToCArray; use lazy_static::lazy_static; // Use initial time stored in static variable as a reference time, @@ -77,16 +76,13 @@ pub struct z_time_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_time_now_as_str(buf: *const c_char, len: usize) -> *const c_char { - if len == 0 { + if len == 0 || buf.is_null() { return buf; } let datetime: DateTime = SystemTime::now().into(); let s = datetime.format("%Y-%m-%dT%H:%M:%SZ").to_string(); - let sb = s.as_bytes(); - let max_len = min(len - 1, s.len()); - let b = slice::from_raw_parts_mut(buf as *mut u8, max_len + 1); - b[0..max_len].copy_from_slice(&sb[0..max_len]); - b[max_len] = 0; + let res = s.as_str().copy_to_c_array(buf as *mut c_void, len - 1); + *((buf as usize + res) as *mut c_char) = 0; buf } diff --git a/src/scouting.rs b/src/scouting.rs index 6df207840..c7dd80be7 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -13,11 +13,11 @@ // use crate::{ z_closure_hello_call, z_config_check, z_config_default, z_config_null, z_config_t, z_id_t, - z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, + z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, CopyableToCArray, }; use async_std::task; use libc::{c_char, c_uint, c_ulong, size_t}; -use std::ffi::CString; +use std::{ffi::CString, os::raw::c_void}; use zenoh::scouting::Hello; use zenoh_protocol::core::{whatami::WhatAmIMatcher, WhatAmI}; use zenoh_util::core::AsyncResolve; @@ -268,3 +268,30 @@ pub extern "C" fn z_scout( }); 0 } + +/// Converts the kind of zenoh entity into a string. +/// +/// Parameters: +/// whatami: A whatami bitmask of zenoh entity kind. +/// buf: Buffer to write a null-terminated string to. +/// len: Maximum number of bytes that can be written to the `buf`. +/// +/// Returns 0 if successful, negative values if whatami contains an invalid bitmask or `buf` is null, +/// or number of remaining bytes, if the null-terminated string size exceeds `len`. +#[no_mangle] +pub extern "C" fn z_whatami_to_str(whatami: u8, buf: *mut c_char, len: usize) -> i8 { + if buf.is_null() || len == 0 { + return -1; + } + match WhatAmIMatcher::try_from(whatami) { + Err(_) => -1, + Ok(w) => { + let s = w.to_str(); + let res = s.copy_to_c_array(buf as *mut c_void, len - 1); + unsafe { + *((buf as usize + res) as *mut c_char) = 0; + } + (s.len() - res) as i8 + } + } +} From 9d76dee75a77f334b26551ebf4c1f4bc132b1faa Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 12 Mar 2024 19:00:19 +0100 Subject: [PATCH 2/2] typo fix --- examples/z_scout.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/z_scout.c b/examples/z_scout.c index 8398bf1fe..1b7b3c21d 100644 --- a/examples/z_scout.c +++ b/examples/z_scout.c @@ -34,8 +34,6 @@ void fprintpid(FILE *stream, z_id_t pid) { void fprintwhatami(FILE *stream, unsigned int whatami) { char buf[64]; - z_time_now_as_str(buf, sizeof(buf)); - fprintf(stream, "%s", buf); z_whatami_to_str(whatami, buf, sizeof(buf)); fprintf(stream, "%s", buf); }